在下面的代码中,AngularJS $http方法调用URL,并提交xsrf对象作为“Request Payload”(在Chrome调试器网络选项卡中描述)。jQuery $。ajax方法做同样的调用,但提交xsrf作为“表单数据”。
如何让AngularJS将xsrf作为表单数据而不是请求有效载荷提交?
var url = 'http://somewhere.com/';
var xsrf = {fkey: 'xsrf key'};
$http({
method: 'POST',
url: url,
data: xsrf
}).success(function () {});
$.ajax({
type: 'POST',
url: url,
data: xsrf,
dataType: 'json',
success: function() {}
});
有一个非常好的教程,介绍了这个和其他相关的东西——提交AJAX表单:AngularJS的方式。
基本上,您需要设置POST请求的报头,以指示您将以URL编码字符串的形式发送表单数据,并将要发送的数据设置为相同的格式
$http({
method : 'POST',
url : 'url',
data : $.param(xsrf), // pass in data as strings
headers : { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request payload)
});
注意,这里使用了jQuery的param()帮助函数将数据序列化为字符串,但如果不使用jQuery,也可以手动执行此操作。
我目前使用的是我在AngularJS谷歌组中找到的解决方案。
$http
.post('/echo/json/', 'json=' + encodeURIComponent(angular.toJson(data)), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).success(function(data) {
$scope.data = data;
});
注意,如果您使用的是PHP,则需要使用类似Symfony 2 HTTP组件的Request::createFromGlobals()来读取该文件,因为$_POST不会自动加载。
从AngularJS v1.4.0开始,就有一个内置的$httpParamSerializer服务,它可以根据文档页面上列出的规则将任何对象转换为HTTP请求的一部分。
它可以这样使用:
$http.post('http://example.com', $httpParamSerializer(formDataObj)).
success(function(data){/* response status 200-299 */}).
error(function(data){/* response status 400-999 */});
请记住,对于正确的表单post, Content-Type头必须更改。要对所有POST请求全局执行此操作,可以使用以下代码(取自Albireo的half-answer):
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
为了只针对当前post,需要修改request-object的headers属性:
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $httpParamSerializer(formDataObj)
};
$http(req);
我取了一些其他的答案,并使一些东西更干净,把这个.config()调用放在你的angular。模块在你的app.js:
.config(['$httpProvider', function ($httpProvider) {
// Intercept POST requests, convert to standard form encoding
$httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$httpProvider.defaults.transformRequest.unshift(function (data, headersGetter) {
var key, result = [];
if (typeof data === "string")
return data;
for (key in data) {
if (data.hasOwnProperty(key))
result.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
}
return result.join("&");
});
}]);
你唯一需要改变的是在创建$http对象时使用属性"params"而不是"data":
$http({
method: 'POST',
url: serviceUrl + '/ClientUpdate',
params: { LangUserId: userId, clientJSON: clients[i] },
})
在上面的例子中,客户端[i]只是JSON对象(没有以任何方式序列化)。如果你使用“params”而不是“data”,angular会使用$httpParamSerializer: https://docs.angularjs.org/api/ng/service/$httpParamSerializer为你序列化对象
这就是我所做的我的需要,在那里我需要发送登录数据API作为表单数据和Javascript对象(userData)正在自动转换为URL编码的数据
var deferred = $q.defer();
$http({
method: 'POST',
url: apiserver + '/authenticate',
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: userData
}).success(function (response) {
//logics
deferred.resolve(response);
}).error(function (err, status) {
deferred.reject(err);
});
这就是我的用户数据
var userData = {
grant_type: 'password',
username: loginData.userName,
password: loginData.password
}