[ajax] 如何將數據發佈為表單數據而不是請求有效內容?



Answers

如果你不想在解決方案中使用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 () {});
Question

在下面的代碼中,AngularJS $http方法調用URL,並將xsrf對像作為“請求負載”提交(如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() {}
});



AngularJS做得很對,因為它在http-request頭文件中執行以下內容類型:

Content-Type: application/json

如果你像我一樣使用php,或者甚至使用Symfony2,你可以簡單地擴展服務器對json標準的兼容性,如下所述: http://silex.sensiolabs.org/doc/cookbook/json_request_body.html : 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以原生方式做這樣的請求。




只需設置Content-Type是不夠的,URL在發送之前對錶單數據進行編碼。 $http.post(url, jQuery.param(data))




這些答案看起來像瘋狂的矯枉過正,有時候,簡單就好了:

$http.post(loginUrl, "userName=" + encodeURIComponent(email) +
                     "&password=" + encodeURIComponent(password) +
                     "&grant_type=password"
).success(function (data) {
//...



在你的應用程序配置 -

$httpProvider.defaults.transformRequest = function (data) {
        if (data === undefined)
            return data;
        var clonedData = $.extend(true, {}, data);
        for (var property in clonedData)
            if (property.substr(0, 1) == '$')
                delete clonedData[property];

        return $.param(clonedData);
    };

通過您的資源請求 -

 headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }



我接受了其他一些答案,並使其更加清晰一些,將這個.config()調用放在您的app.js中的angular.module的末尾:

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



你必須改變的唯一方法是在創建你的$ http對象時使用屬性“params”而不是“data”:

$http({
   method: 'POST',
   url: serviceUrl + '/ClientUpdate',
   params: { LangUserId: userId, clientJSON: clients[i] },
})

在上面的例子中,clients [i]只是JSON對象(沒有以任何方式序列化)。 如果使用“params”而不是“data”,angular將使用$ httpParamSerializer為您序列化對象: https://docs.angularjs.org/api/ng/service/ ://docs.angularjs.org/api/ng/service/ $ httpParamSerializer




為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)
        })
    }

})



Links