在下面的代码中,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,也可以手动执行此操作。

其他回答

对于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);

你可以全局定义行为:

$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";

所以你不必每次都重新定义它:

$http.post("/handle/post", {
    foo: "FOO",
    bar: "BAR"
}).success(function (data, status, headers, config) {
    // TODO
}).error(function (data, status, headers, config) {
    // TODO
});

我目前使用的是我在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不会自动加载。

为post创建一个适配器服务:

services.service('Http', function ($http) {

    var self = this

    this.post = function (url, data) {
        return $http({
            method: 'POST',
            url: url,
            data: $.param(data),
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })
    }

}) 

在你的控制器或其他地方使用它:

ctrls.controller('PersonCtrl', function (Http /* our service */) {
    var self = this
    self.user = {name: "Ozgur", eMail: null}

    self.register = function () {
        Http.post('/user/register', self.user).then(function (r) {
            //response
            console.log(r)
        })
    }

})

这就是我所做的我的需要,在那里我需要发送登录数据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
            }