有人能告诉我为什么下面的语句没有将post数据发送到指定的url吗?url被调用,但在服务器上,当我打印$_POST -我得到一个空数组。如果我在控制台中打印消息,然后将其添加到数据-它显示了正确的内容。
$http.post('request-url', { 'message' : message });
我也尝试过将数据作为字符串(具有相同的结果):
$http.post('request-url', "message=" + message);
当我以以下格式使用它时,它似乎正在工作:
$http({
method: 'POST',
url: 'request-url',
data: "message=" + message,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
但是是否有一种方法可以用$http.post() -我总是必须包括头以便它工作吗?我相信上面的内容类型是指定发送数据的格式,但我可以把它作为javascript对象发送吗?
只是提出一个现代化版本的@FelipeMiosso的答案:
.config(["$httpProvider", function ($httpProvider) {
function buildKey(parentKey, subKey) {
return parentKey + "[" + subKey + "]";
}
function buildObject(key, value) {
var object = {};
object[key] = value;
return object;
}
function join(array) {
return array.filter(function (entry) {
return entry;
}).join("&");
}
function arrayToQueryString(parentKey, array) {
return join(array.map(function (value, subKey) {
return toQueryString(buildObject(buildKey(parentKey, subKey), value));
}));
}
function objectToQueryString(parentKey, object) {
return join(Object.keys(object).map(function (subKey) {
return toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]));
}));
}
function toQueryString(input) {
return join(Object.keys(input).map(function (key) {
var value = input[key];
if (value instanceof Array) {
return arrayToQueryString(key, value);
} else if (value instanceof Object) {
return objectToQueryString(key, value);
} else if (undefined !== value && null !== value) {
return encodeURIComponent(key) + "=" + encodeURIComponent(value);
} else {
return "";
}
}));
}
function isQueryStringEligible(input) {
return null !== input && "object" === typeof input && "[object File]" !== String(input);
}
var interceptor = [function () {
return {
request: function (config) {
if (0 <= ["post", "put", "patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
config.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
config.data = toQueryString(config.data);
}
return config;
}
};
}];
$httpProvider.interceptors.push(interceptor);
}])
ES6版本:
.config(["$httpProvider", function ($httpProvider) {
"use strict";
const buildKey = (parentKey, subKey) => `${parentKey}[${subKey}]`;
const buildObject = (key, value) => ({ [key]: value });
const join = (array) => array.filter((entry) => entry).join("&");
const arrayToQueryString = (parentKey, array) =>
join(array.map((value, subKey) =>
toQueryString(buildObject(buildKey(parentKey, subKey), value))));
const objectToQueryString = (parentKey, object) =>
join(Object.keys(object).map((subKey) =>
toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]))));
const toQueryString = (input) => join(Object.keys(input).map((key) => {
const value = input[key];
if (value instanceof Array) {
return arrayToQueryString(key, value);
} else if (value instanceof Object) {
return objectToQueryString(key, value);
} else if (undefined !== value && null !== value) {
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
} else {
return "";
}
}));
const isQueryStringEligible = (input) =>
null !== input && "object" === typeof input && "[object File]" !== String(input);
const interceptor = [() => ({
request(config) {
if (0 <= ["post", "put", "patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
config.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
config.data = toQueryString(config.data);
}
return config;
}
})];
$httpProvider.interceptors.push(interceptor);
}])
我知道已经接受了答案。但是,如果这个答案因为任何原因不适合他们,下面的内容可能会对未来的读者有所帮助。
Angular不会像jQuery那样使用ajax。当我尝试按照指南修改angular $httpprovider时,我遇到了其他问题。例如,我使用codeigniter,其中$this->input->is_ajax_request()函数总是失败(这是由另一个程序员编写的,并在全局使用,所以不能改变)说这不是真正的ajax请求。
为了解决这个问题,我接受了延期承诺的帮助。我在Firefox和ie9上进行了测试,效果很好。
我在angular代码的外部定义了以下函数。这个函数使常规jquery ajax调用和返回延迟/承诺(我仍在学习)对象。
function getjQueryAjax(url, obj){
return $.ajax({
type: 'post',
url: url,
cache: true,
data: obj
});
}
然后我用下面的代码称它为角代码。请注意,我们必须使用$scope.$apply()手动更新$scope。
var data = {
media: "video",
scope: "movies"
};
var rPromise = getjQueryAjax("myController/getMeTypes" , data);
rPromise.success(function(response){
console.log(response);
$scope.$apply(function(){
$scope.testData = JSON.parse(response);
console.log($scope.testData);
});
}).error(function(){
console.log("AJAX failed!");
});
这可能不是完美的答案,但它允许我在angular中使用jquery ajax调用,并允许我更新$scope。
我在使用AngularJS和Node.js + Express 4 + Router时也遇到了同样的问题
路由器期望从post的请求中得到数据。如果我遵循Angular Docs中的例子,这个主体总是空的
符号1
$http.post('/someUrl', {msg:'hello word!'})
但如果我把它用在数据中
符号2
$http({
withCredentials: false,
method: 'post',
url: yourUrl,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: postData
});
编辑1:
否则node.js路由器将期望req中的数据。正文(如使用符号1):
req.body.msg
它还将信息作为JSON有效负载发送。在json和x-www-form-urlencoded中有数组的某些情况下,这是更好的。
它工作。希望能有所帮助。
It's not angular's fault. Angular is designed to work in JSON world. So when $http service send AJAX request, it send all your data as a payload, not as form-data so that your backend application can handle it. But jQuery does some things internally. You instruct jQuery's $ajax module to bind form-data as JSON but before sending AJAX request, it serialized JSON and add application/x-www-form-urlencoded header. This way your backend application able to received form-data in form of post parameters and not JSON.
但是你可以修改angular $http服务的默认行为
添加标题
序列化json
$httpParamSerializerJQLike是angular的内置服务,它以同样的方式序列化json。jQuery的参数。
$http({
method: 'POST',
url: 'request-url',
data: $httpParamSerializerJQLike(json-form-data),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;'
}
});
如果你需要一个插件先将表单数据序列化成JSON,可以使用这个插件https://github.com/marioizquierdo/jquery.serializeJSON
在我的例子中,我是这样解决问题的:
var deferred = $q.defer();
$http({
method: 'POST',
url: 'myUri',
data: $.param({ param1: 'blablabla', param2: JSON.stringify(objJSON) }),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(
function(res) {
console.log('succes !', res.data);
deferred.resolve(res.data);
},
function(err) {
console.log('error...', err);
deferred.resolve(err);
}
);
return deferred.promise;
您需要使用JSON。为每个包含JSON对象的参数进行stringify,然后使用"$. stringify "构建数据对象。param”:-)
注意:我的“objJSON”是一个JSON对象,包含数组,整数,字符串和html内容。他的总大小是>3500个字符。