在下面的代码中,AngularJS $http
方法调用URL,并将xsrf对象作为"Request Payload"提交(如Chrome调试器网络选项卡中所述) . jQuery $.ajax
方法执行相同的调用,但将xsrf提交为"Form Data" .
如何让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() {}
});
22 回答
我目前正在AngularJS谷歌小组中使用以下解决方案found .
请注意,如果您需要使用类似Symfony 2 HTTP组件的
Request::createFromGlobals()
来读取此内容,因为$ _POST将不会自动加载它 .仅设置Content-Type是不够的,url在发送之前对表单数据进行编码 .
$http.post(url, jQuery.param(data))
我拿了一些其他的答案并且做了一些更清洁的东西,把这个
.config()
调用放在app.js中angular.module的末尾:对于Symfony2用户:
如果您不想更改javascript中的任何内容以使其工作,您可以在symfony app中进行以下修改:
创建一个扩展Symfony \ Component \ HttpFoundation \ Request类的类:
现在在app_dev.php(或您使用的任何索引文件)中使用您的类
这不是一个直接的答案,而是一个略有不同的设计方向:
Do not post the data as a form, but as a JSON object to be directly mapped to server-side object, or use REST style path variable
现在我知道,由于您尝试传递XSRF密钥,因此这两种选项都不适用于您的情况 . 将它映射到这样的路径变量是一个可怕的设计:
因为本质上你也想把xsrf键传递到其他路径,
/login
,/book-appointment
等你不想弄乱你漂亮的URL有趣的是,将它添加为对象字段也是不合适的,因为现在每个json对象都传递给服务器,你必须添加字段
您当然不希望在服务器端类上添加另一个字段,该字段与域对象没有直接的语义关联 .
在我看来,传递xsrf密钥的最佳方法是通过HTTP头 . 许多xsrf保护服务器端Web框架库都支持此功能 . For example in Java Spring, you can pass it using X-CSRF-TOKEN header .
Angular将JS对象绑定到UI对象的出色能力意味着我们可以摆脱一起发布表单的做法,而不是发布JSON . JSON可以轻松地反序列化为服务器端对象,并支持复杂的数据结构,如映射,数组,嵌套对象等 .
如何在表单有效负载中发布数组?也许是这样的:
或这个:
两者都是糟糕的设计..
有一个非常好的教程可以解释这个和其他相关的东西 - Submitting AJAX Forms: The AngularJS Way .
基本上,您需要设置POST请求的标头以指示您将表单数据作为URL编码的字符串发送,并将要发送的数据设置为相同的格式
请注意,此处使用jQuery的param()辅助函数将数据序列化为字符串,但如果不使用jQuery,也可以手动执行此操作 .
为帖子创建适配器服务:
在控制器或其他任何地方使用它:
作为一种解决方法,您可以简单地使接收POST的代码响应application / json数据 . 对于PHP,我添加了下面的代码,允许我以表格编码或JSON的方式POST .
使用AngularJS
$http
服务并使用其post
方法或配置$http
函数 .AngularJS正在执行它,因为它在http-request标头内执行以下内容类型:
如果您使用像我这样的PHP,或者甚至使用Symfony2,您可以简单地扩展您的服务器兼容性,如此处所述的json标准:http://silex.sensiolabs.org/doc/cookbook/json_request_body.html
Symfony2方式(例如在DefaultController中):
优点是,您不需要使用jQuery param,并且您可以使用AngularJS以其本机方式执行此类请求 .
需要将以下行添加到传递的$ http对象:
传递的数据应转换为URL编码的字符串:
所以你有类似的东西:
来自:https://groups.google.com/forum/#!msg/angular/5nAedJ1LyO0/4Vj_72EZcDsJ
更新
要使用AngularJS V1.4添加的新服务,请参阅
这些答案看起来像疯狂的矫枉过正,有时,简单就是更好:
在您的应用配置中 -
根据您的资源请求 -
完整答案(自角度1.4) . 你需要包含de dependency $ httpParamSerializer
在创建$ http对象时,唯一需要更改的是使用属性“params”而不是“data”:
在上面的示例中,clients [i]只是JSON对象(不以任何方式序列化) . 如果您使用"params"而不是"data" angular将使用$ httpParamSerializer为您序列化对象:https://docs.angularjs.org/api/ng/service/ $ httpParamSerializer
如果你不想在解决方案中使用jQuery,你可以试试这个 . 解决方案从这里抓到https://stackoverflow.com/a/1714899/1784301
请结账! https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
从AngularJS v1.4.0开始,有一个内置的
$httpParamSerializer
服务,它根据docs page上列出的规则将任何对象转换为HTTP请求的一部分 .它可以像这样使用:
请记住,对于正确的表单帖子,必须更改
Content-Type
Headers . 要为所有POST请求全局执行此操作,可以使用此代码(取自Albireo的半答案):要做到这一点只为了当前帖子,需要修改请求对象的
headers
属性:您可以全局定义行为:
所以你不必每次都重新定义它:
围绕这个问题的持续混乱激发了我写一篇关于它的博客文章 . 我在这篇文章中提出的解决方案优于您当前的最高评级解决方案,因为它不会限制您为$ http服务调用参数化数据对象;即使用我的解决方案,您可以继续将实际数据对象传递到$ http.post()等,并仍然可以实现所需的结果 .
此外,最受欢迎的答案依赖于在$ .param()函数的页面中包含完整的jQuery,而我的解决方案是jQuery不可知,纯粹的AngularJS就绪 .
http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
希望这可以帮助 .
您可以尝试以下解决方案
这就是我正在为我的需要而做的事情,我需要将登录数据作为表单数据发送到API,并且Javascript对象(userData)会自动转换为URL编码数据
这是我的Userdata的方式