有人能告诉我为什么下面的语句没有将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对象发送吗?
没有找到如何使用$http的完整代码片段。Post方法将数据发送到服务器,以及为什么在这种情况下它不工作。
以下代码段的解释…
我使用jQuery $。param函数将JSON数据序列化为www post data
在配置变量中设置Content-Type,该变量将随angularJS $http请求一起传递。通知服务器我们将以WWW Post格式发送数据。
注意$ http。post方法,我发送的第一个参数作为url,第二个参数作为数据(序列化)和第三个参数作为配置。
剩下的代码是自己理解的。
$scope.SendData = function () {
// use $.param jQuery function to serialize data from JSON
var data = $.param({
fName: $scope.firstName,
lName: $scope.lastName
});
var config = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
}
}
$http.post('/ServerRequest/PostDataResponse', data, config)
.success(function (data, status, headers, config) {
$scope.PostDataResponse = data;
})
.error(function (data, status, header, config) {
$scope.ResponseDetails = "Data: " + data +
"<hr />status: " + status +
"<hr />headers: " + header +
"<hr />config: " + config;
});
};
查看$http的代码示例。Post方法在这里。
如果使用Angular >= 1.4,下面是使用Angular提供的序列化器的最简洁的解决方案:
angular.module('yourModule')
.config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
$httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
});
然后你可以简单地在你的应用的任何地方做这个:
$http({
method: 'POST',
url: '/requesturl',
data: {
param1: 'value1',
param2: 'value2'
}
});
它会正确地将数据序列化为param1=value1¶m2=value2,并将其发送到/requesturl,并使用application/x-www-form-urlencoded;charset=utf-8内容类型报头,因为它通常是端点上POST请求所期望的。
博士TL;
在我的研究中,我发现这个问题的答案有很多种;一些是非常复杂的,依赖于自定义函数,一些依赖于jQuery和一些是不完整的,建议你只需要设置头。
如果您只是设置Content-Type报头,端点将看到POST数据,但它不会是标准格式,因为除非您提供一个字符串作为数据,或者手动序列化数据对象,否则在默认情况下,它都将被序列化为JSON,并且可能在端点被错误地解释。
例如,如果在上面的例子中没有设置正确的序列化器,它将在端点中被视为:
{"param1":"value1","param2":"value2"}
这可能导致意想不到的解析,例如ASP。NET将其视为空参数名,用{"param1":"value1","param2":"value2"}作为值;或者Fiddler以另一种方式解释它,用{"param1":"value1","param2":"value2"}作为参数名,用null作为值。
我一直在使用公认的答案的代码(Felipe的代码)一段时间,它工作得很好(谢谢,Felipe!)。
但是,最近我发现它有空对象或数组的问题。
例如,当提交这个对象时:
{
A: 1,
B: {
a: [ ],
},
C: [ ],
D: "2"
}
PHP似乎根本看不到B和C。结果是这样的:
[
"A" => "1",
"B" => "2"
]
看看实际的请求在Chrome显示:
A: 1
:
D: 2
我写了一个替代代码片段。它似乎在我的用例中工作得很好,但我还没有对它进行广泛测试,所以请谨慎使用。
我使用TypeScript,因为我喜欢强类型,但它很容易转换为纯JS:
angular.module("MyModule").config([ "$httpProvider", function($httpProvider: ng.IHttpProvider) {
// Use x-www-form-urlencoded Content-Type
$httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
function phpize(obj: Object | any[], depth: number = 1): string[] {
var arr: string[] = [ ];
angular.forEach(obj, (value: any, key: string) => {
if (angular.isObject(value) || angular.isArray(value)) {
var arrInner: string[] = phpize(value, depth + 1);
var tmpKey: string;
var encodedKey = encodeURIComponent(key);
if (depth == 1) tmpKey = encodedKey;
else tmpKey = `[${encodedKey}]`;
if (arrInner.length == 0) {
arr.push(`${tmpKey}=`);
}
else {
arr = arr.concat(arrInner.map(inner => `${tmpKey}${inner}`));
}
}
else {
var encodedKey = encodeURIComponent(key);
var encodedValue;
if (angular.isUndefined(value) || value === null) encodedValue = "";
else encodedValue = encodeURIComponent(value);
if (depth == 1) {
arr.push(`${encodedKey}=${encodedValue}`);
}
else {
arr.push(`[${encodedKey}]=${encodedValue}`);
}
}
});
return arr;
}
// Override $http service's default transformRequest
(<any>$httpProvider.defaults).transformRequest = [ function(data: any) {
if (!angular.isObject(data) || data.toString() == "[object File]") return data;
return phpize(data).join("&");
} ];
} ]);
它的效率比Felipe的代码低,但我认为这无关紧要,因为与HTTP请求本身的整体开销相比,它应该是即时的。
现在PHP显示:
[
"A" => "1",
"B" => [
"a" => ""
],
"C" => "",
"D" => "2"
]
据我所知,让PHP识别B.a和C是空数组是不可能的,但至少键会出现,当代码依赖于某个结构时,这很重要,即使它内部实际上是空的。
还要注意,它将未定义的和null转换为空字符串。
通过使用非常简单的方法,我们可以这样做:
$http({
url : "submit_form_adv.php",
method : 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p)+' = '+encodeURIComponent(obj[p]));
return str.join('&');
},
data : {sample_id : 100, sample_name: 'Abin John'},
}).success(function(data, status, headers, config) {
}).error(function(ata, status, headers, config) {
});