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

当前回答

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

其他回答

这并不是一个直接的答案,而是一个略有不同的设计方向:

不要将数据作为表单发布,而是作为JSON对象直接映射到服务器端对象,或者使用REST风格的路径变量

现在我知道这两个选项都不适合您的情况,因为您试图传递一个XSRF键。像这样把它映射成一个路径变量是一个糟糕的设计:

http://www.someexample.com/xsrf/{xsrfKey}

因为本质上你会想要传递xsrf密钥到其他路径,/login, /book-appointment等,你不想弄乱你漂亮的URL

有趣的是,将它作为对象字段添加也不合适,因为现在你传递给服务器的每个json对象都必须添加字段

{
  appointmentId : 23,
  name : 'Joe Citizen',
  xsrf : '...'
}

您当然不希望在服务器端类上添加另一个与域对象没有直接语义关联的字段。

在我看来,传递xsrf密钥的最佳方式是通过HTTP报头。许多xsrf保护服务器端web框架库都支持这一点。例如,在Java Spring中,您可以使用X-CSRF-TOKEN头传递它。

Angular出色的将JS对象绑定到UI对象的能力意味着我们可以摆脱一起发布表单的做法,而是发布JSON。JSON可以很容易地反序列化为服务器端对象,并支持复杂的数据结构,如映射、数组、嵌套对象等。

如何在表单有效负载中发布数组?也许是这样的:

shopLocation=downtown&daysOpen=Monday&daysOpen=Tuesday&daysOpen=Wednesday

或:

shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday

都是糟糕的设计。

如果你不想在解决方案中使用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服务,并使用它的post方法或配置$http函数。

有一个非常好的教程,介绍了这个和其他相关的东西——提交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,也可以手动执行此操作。

你可以全局定义行为:

$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
});