在下面的代码中,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() {}
});

当前回答

如果你不想在解决方案中使用jQuery,你可以试试这个。解决方案从这里获取https://stackoverflow.com/a/1714899/1784301

$http({
    method: 'POST',
    url: url,
    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: xsrf
}).success(function () {});

其他回答

AngularJS的做法是正确的,因为它在http-request头中执行了以下内容类型:

Content-Type: application/json

如果你像我一样使用php,甚至使用Symfony2,你可以简单地扩展json标准的服务器兼容性:http://silex.sensiolabs.org/doc/cookbook/json_request_body.html

Symfony2方式(例如在你的DefaultController中):

$request = $this->getRequest();
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
    $data = json_decode($request->getContent(), true);
    $request->request->replace(is_array($data) ? $data : array());
}
var_dump($request->request->all());

好处是,你不需要使用jQuery参数,你可以使用AngularJS的原生方式来做这样的请求。

你可以试试下面的溶液

$http({
        method: 'POST',
        url: url-post,
        data: data-post-object-json,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        transformRequest: function(obj) {
            var str = [];
            for (var key in obj) {
                if (obj[key] instanceof Array) {
                    for(var idx in obj[key]){
                        var subObj = obj[key][idx];
                        for(var subKey in subObj){
                            str.push(encodeURIComponent(key) + "[" + idx + "][" + encodeURIComponent(subKey) + "]=" + encodeURIComponent(subObj[subKey]));
                        }
                    }
                }
                else {
                    str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]));
                }
            }
            return str.join("&");
        }
    }).success(function(response) {
          /* Do something */
        });

下面一行需要添加到传递的$http对象中:

headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}

并且传递的数据应该转换为url编码的字符串:

> $.param({fkey: "key"})
'fkey=key'

你会得到这样的结果:

$http({
    method: 'POST',
    url: url,
    data: $.param({fkey: "key"}),
    headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})

来自:https://groups.google.com/forum/ # !味精naedj1lyo0/4vj_72ezcdsj /角度/ 5

更新

要使用AngularJS V1.4中添加的新服务,请参见

只使用AngularJS服务的url编码变量

从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);

对于Symfony2用户:

如果你不想改变javascript中的任何东西,你可以在symfony app中做这些修改:

创建一个扩展Symfony\Component\HttpFoundation\Request类的类:

<?php

namespace Acme\Test\MyRequest;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ParameterBag;

class MyRequest extends Request{


/**
* Override and extend the createFromGlobals function.
* 
* 
*
* @return Request A new request
*
* @api
*/
public static function createFromGlobals()
{
  // Get what we would get from the parent
  $request = parent::createFromGlobals();

  // Add the handling for 'application/json' content type.
  if(0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/json')){

    // The json is in the content
    $cont = $request->getContent();

    $json = json_decode($cont);

    // ParameterBag must be an Array.
    if(is_object($json)) {
      $json = (array) $json;
  }
  $request->request = new ParameterBag($json);

}

return $request;

}

}

现在使用app_dev.php中的类(或您使用的任何索引文件)

// web/app_dev.php

$kernel = new AppKernel('dev', true);
// $kernel->loadClassCache();
$request = ForumBundleRequest::createFromGlobals();

// use your class instead
// $request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);