$http的任何方式。发送请求参数而不是JSON?

时间:2022-08-22 17:46:09

I have some old code that is making an AJAX POST request through jQuery's post method and looks something like this:

我有一些旧的代码通过jQuery的POST方法发出AJAX POST请求,看起来是这样的:

$.post("/foo/bar", requestData,
    function(responseData)
    {
        //do stuff with response
    }

requestData is just a javascript object with some basic string properties.

requestData只是一个带有一些基本字符串属性的javascript对象。

I'm in the process of moving our stuff over to use Angular, and I want to replace this call with $http.post. I came up with the following:

我正在将我们的东西移动到使用angle的过程中,我想用$http.post替换这个调用。我想到了以下几点:

$http.post("/foo/bar", requestData).success(
    function(responseData) {
        //do stuff with response
    }
});

When I did this, I got a 500 error response from the server. Using Firebug, I found that this sent the request body like this:

当我这样做时,我从服务器得到了500个错误响应。使用Firebug,我发现它发送请求体如下:

{"param1":"value1","param2":"value2","param3":"value3"}

The successful jQuery $.post sends the body like this:

成功的jQuery美元。post发送身体如下:

param1=value1&param2=value2&param3=value3

The endpoint I am hitting is expecting request parameters and not JSON. So, my question is is there anyway to tell $http.post to send up the javascript object as request parameters instead of JSON? Yes, I know I could construct the string myself from the object, but I want to know if Angular provides anything for this out of the box.

我要打击的端点期望的是请求参数,而不是JSON。我的问题是,是否存在告诉$http的方法。post将javascript对象作为请求参数而不是JSON发送?是的,我知道我可以自己从物体上构造弦,但我想知道角度是否为这个盒子提供了任何东西。

12 个解决方案

#1


140  

I think the params config parameter won't work here since it adds the string to the url instead of the body but to add to what Infeligo suggested here is an example of the global override of a default transform (using jQuery param as an example to convert the data to param string).

我认为参数配置参数不会在这里工作因为它添加字符串url而不是身体而是添加到这里Infeligo提出的全球覆盖默认转换的一个例子(使用jQuery参数为例,将数据转换为参数字符串)。

Set up global transformRequest function:

设置全局transformRequest函数:

var app = angular.module('myApp');

app.config(function ($httpProvider) {
    $httpProvider.defaults.transformRequest = function(data){
        if (data === undefined) {
            return data;
        }
        return $.param(data);
    }
});

That way all calls to $http.post will automatically transform the body to the same param format used by the jQuery $.post call.

这样所有的调用都是$http。post将自动将主体转换为jQuery $使用的param格式。post调用。

Note you may also want to set the Content-Type header per call or globally like this:

注意,您可能还想设置每个调用的内容类型头,或全局设置如下:

$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

Sample non-global transformRequest per call:

每个调用的非全局流程请求示例:

    var transform = function(data){
        return $.param(data);
    }

    $http.post("/foo/bar", requestData, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        transformRequest: transform
    }).success(function(responseData) {
        //do stuff with response
    });

#2


20  

If using Angular >= 1.4, here's the cleanest solution I've found that doesn't rely on anything custom or external:

如果使用角度>= 1.4,这是我发现的最干净的解决方案,不依赖于任何定制或外部:

angular.module('yourModule')
  .config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
    $httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
});

And then you can do this anywhere in your app:

然后你可以在你的应用中任何地方这样做:

$http({
  method: 'POST',
  url: '/requesturl',
  data: {
    param1: 'value1',
    param2: 'value2'
  }
});

And it will correctly serialize the data as param1=value1&param2=value2 and send it to /requesturl with the application/x-www-form-urlencoded; charset=utf-8 Content-Type header as it's normally expected with POST requests on endpoints.

将数据正确序列化为param1=value1&param2=value2,然后用应用/x-www-form- urlencodes发送给/requesturl;charset=utf-8 Content-Type头,这是在端点上POST请求时通常需要的。

#3


17  

From AngularJS documentation:

从AngularJS文档:

params – {Object.} – Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.

参数- {对象。} -将被转换为?key1=value1&key2=value2的字符串或对象的映射。如果该值不是字符串,那么它将被JSONified。

So, provide string as parameters. If you don't want that, then use transformations. Again, from the documentation:

因此,提供字符串作为参数。如果您不想要那样,那么使用转换。再次,从文档:

To override these transformation locally, specify transform functions as transformRequest and/or transformResponse properties of the config object. To globally override the default transforms, override the $httpProvider.defaults.transformRequest and $httpProvider.defaults.transformResponse properties of the $httpProvider.

要在本地覆盖这些转换,请将转换函数指定为配置对象的transformRequest和/或transformResponse属性。要全局覆盖默认转换,请覆盖$httpProvider. transformrequest和$httpProvider.defaults.transformResponse属性。

Refer to documentation for more details.

更多细节请参阅文档。

#4


15  

Use jQuery's $.param function to serialize the JSON data in requestData.

使用jQuery的美元。param函数,用于序列化requestData中的JSON数据。

In short, using similar code as yours:

简而言之,使用与您类似的代码:

$http.post("/foo/bar",
$.param(requestData),
{
    headers:
    {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }
}
).success(
    function(responseData) {
        //do stuff with response
    }
});

For using this, you have to include jQuery in your page along with AngularJS.

要使用它,必须在页面中包含jQuery和AngularJS。

#5


7  

Note that as of Angular 1.4, you can serialize the form data without using jQuery.

注意,从角度1.4开始,您可以不使用jQuery就序列化表单数据。

In the app.js:

app.js:

module.run(function($http, $httpParamSerializerJQLike) {
  $http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
});

Then in your controller:

然后在你的控制器:

$http({
    method: 'POST',
    url: myUrl',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: myData
});

#6


5  

This might be a bit of a hack, but I avoided the issue and converted the json into PHP's POST array on the server side:

这可能有点麻烦,但我避免了这个问题,并将json转换为PHP在服务器端的POST数组:

$_POST = json_decode(file_get_contents('php://input'), true);

#7


5  

I have problems as well with setting custom http authentication because $resource cache the request.

设置自定义http身份验证也有问题,因为$resource缓存请求。

To make it work you have to overwrite the existing headers by doing this

要使其工作,您必须通过这样做来覆盖现有的头。

var transformRequest = function(data, headersGetter){
  var headers = headersGetter();
  headers['Authorization'] = 'WSSE profile="UsernameToken"';
  headers['X-WSSE'] = 'UsernameToken ' + nonce
  headers['Content-Type'] = 'application/json';
};

return $resource(
  url,
    {
    },
    {
      query: {
        method: 'POST',
        url: apiURL + '/profile',
        transformRequest: transformRequest,
        params: {userId: '@userId'}
      },
    }
);

I hope I was able to help someone. It took me 3 days to figure this one out.

我希望我能帮助某人。我花了3天时间才弄明白这个。

#8


4  

Modify the default headers:

修改默认的标题:

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

Then use JQuery's $.param method:

然后使用JQuery的美元。参数的方法:

var payload = $.param({key: value});
$http.post(targetURL, payload);

#9


3  

   .controller('pieChartController', ['$scope', '$http', '$httpParamSerializerJQLike', function($scope, $http, $httpParamSerializerJQLike) {
        var data = {
                TimeStamp : "2016-04-25 12:50:00"
        };
        $http({
            method: 'POST',
            url: 'serverutilizationreport',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            data: $httpParamSerializerJQLike(data),
        }).success(function () {});
    }
  ]);

#10


2  

Quick adjustment - for those of you having trouble with the global configuration of the transformRequest function, here's the snippet i'm using to get rid of the Cannot read property 'jquery' of undefined error:

快速调整——对于那些在transformRequest函数的全局配置上有问题的人,下面是我用来消除“无法读取”属性“jquery”的未定义错误的代码片段:

$httpProvider.defaults.transformRequest = function(data) {
        return data != undefined ? $.param(data) : null;
    }

#11


1  

You can also solve this problem without changing code in server, changing header in $http.post call and use $_POST the regular way. Explained here: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

您还可以解决这个问题,而无需更改服务器中的代码,只需更改$http中的头。按常规方式调用和使用$_POST。解释:http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

#12


0  

I found many times problematic behavior of this whole. I used it from express (without typings) and the bodyParser (with the dt~body-parser typings).

我发现这个整体有很多问题。我从express(没有排版)和bodyParser(使用dt~body-parser排版)中使用它。

I didn't try to upload a file, instead simply to interpret a JSON given in a post string.

我没有尝试上传一个文件,而是简单地解释一个post字符串中给出的JSON。

The request.body was simply an empty json ({}).

请求。body只是一个空的json({})。

After a lot of investigation finally this worked for me:

经过大量的调查,这对我来说很有效:

import { json } from 'body-parser';
...
app.use(json()); <-- should be defined before the first POST handler!

It may be also important to give the application/json content type in the request string from the client side.

在客户端请求字符串中提供应用程序/json内容类型也很重要。

#1


140  

I think the params config parameter won't work here since it adds the string to the url instead of the body but to add to what Infeligo suggested here is an example of the global override of a default transform (using jQuery param as an example to convert the data to param string).

我认为参数配置参数不会在这里工作因为它添加字符串url而不是身体而是添加到这里Infeligo提出的全球覆盖默认转换的一个例子(使用jQuery参数为例,将数据转换为参数字符串)。

Set up global transformRequest function:

设置全局transformRequest函数:

var app = angular.module('myApp');

app.config(function ($httpProvider) {
    $httpProvider.defaults.transformRequest = function(data){
        if (data === undefined) {
            return data;
        }
        return $.param(data);
    }
});

That way all calls to $http.post will automatically transform the body to the same param format used by the jQuery $.post call.

这样所有的调用都是$http。post将自动将主体转换为jQuery $使用的param格式。post调用。

Note you may also want to set the Content-Type header per call or globally like this:

注意,您可能还想设置每个调用的内容类型头,或全局设置如下:

$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

Sample non-global transformRequest per call:

每个调用的非全局流程请求示例:

    var transform = function(data){
        return $.param(data);
    }

    $http.post("/foo/bar", requestData, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        transformRequest: transform
    }).success(function(responseData) {
        //do stuff with response
    });

#2


20  

If using Angular >= 1.4, here's the cleanest solution I've found that doesn't rely on anything custom or external:

如果使用角度>= 1.4,这是我发现的最干净的解决方案,不依赖于任何定制或外部:

angular.module('yourModule')
  .config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
    $httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
});

And then you can do this anywhere in your app:

然后你可以在你的应用中任何地方这样做:

$http({
  method: 'POST',
  url: '/requesturl',
  data: {
    param1: 'value1',
    param2: 'value2'
  }
});

And it will correctly serialize the data as param1=value1&param2=value2 and send it to /requesturl with the application/x-www-form-urlencoded; charset=utf-8 Content-Type header as it's normally expected with POST requests on endpoints.

将数据正确序列化为param1=value1&param2=value2,然后用应用/x-www-form- urlencodes发送给/requesturl;charset=utf-8 Content-Type头,这是在端点上POST请求时通常需要的。

#3


17  

From AngularJS documentation:

从AngularJS文档:

params – {Object.} – Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.

参数- {对象。} -将被转换为?key1=value1&key2=value2的字符串或对象的映射。如果该值不是字符串,那么它将被JSONified。

So, provide string as parameters. If you don't want that, then use transformations. Again, from the documentation:

因此,提供字符串作为参数。如果您不想要那样,那么使用转换。再次,从文档:

To override these transformation locally, specify transform functions as transformRequest and/or transformResponse properties of the config object. To globally override the default transforms, override the $httpProvider.defaults.transformRequest and $httpProvider.defaults.transformResponse properties of the $httpProvider.

要在本地覆盖这些转换,请将转换函数指定为配置对象的transformRequest和/或transformResponse属性。要全局覆盖默认转换,请覆盖$httpProvider. transformrequest和$httpProvider.defaults.transformResponse属性。

Refer to documentation for more details.

更多细节请参阅文档。

#4


15  

Use jQuery's $.param function to serialize the JSON data in requestData.

使用jQuery的美元。param函数,用于序列化requestData中的JSON数据。

In short, using similar code as yours:

简而言之,使用与您类似的代码:

$http.post("/foo/bar",
$.param(requestData),
{
    headers:
    {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }
}
).success(
    function(responseData) {
        //do stuff with response
    }
});

For using this, you have to include jQuery in your page along with AngularJS.

要使用它,必须在页面中包含jQuery和AngularJS。

#5


7  

Note that as of Angular 1.4, you can serialize the form data without using jQuery.

注意,从角度1.4开始,您可以不使用jQuery就序列化表单数据。

In the app.js:

app.js:

module.run(function($http, $httpParamSerializerJQLike) {
  $http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
});

Then in your controller:

然后在你的控制器:

$http({
    method: 'POST',
    url: myUrl',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: myData
});

#6


5  

This might be a bit of a hack, but I avoided the issue and converted the json into PHP's POST array on the server side:

这可能有点麻烦,但我避免了这个问题,并将json转换为PHP在服务器端的POST数组:

$_POST = json_decode(file_get_contents('php://input'), true);

#7


5  

I have problems as well with setting custom http authentication because $resource cache the request.

设置自定义http身份验证也有问题,因为$resource缓存请求。

To make it work you have to overwrite the existing headers by doing this

要使其工作,您必须通过这样做来覆盖现有的头。

var transformRequest = function(data, headersGetter){
  var headers = headersGetter();
  headers['Authorization'] = 'WSSE profile="UsernameToken"';
  headers['X-WSSE'] = 'UsernameToken ' + nonce
  headers['Content-Type'] = 'application/json';
};

return $resource(
  url,
    {
    },
    {
      query: {
        method: 'POST',
        url: apiURL + '/profile',
        transformRequest: transformRequest,
        params: {userId: '@userId'}
      },
    }
);

I hope I was able to help someone. It took me 3 days to figure this one out.

我希望我能帮助某人。我花了3天时间才弄明白这个。

#8


4  

Modify the default headers:

修改默认的标题:

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

Then use JQuery's $.param method:

然后使用JQuery的美元。参数的方法:

var payload = $.param({key: value});
$http.post(targetURL, payload);

#9


3  

   .controller('pieChartController', ['$scope', '$http', '$httpParamSerializerJQLike', function($scope, $http, $httpParamSerializerJQLike) {
        var data = {
                TimeStamp : "2016-04-25 12:50:00"
        };
        $http({
            method: 'POST',
            url: 'serverutilizationreport',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            data: $httpParamSerializerJQLike(data),
        }).success(function () {});
    }
  ]);

#10


2  

Quick adjustment - for those of you having trouble with the global configuration of the transformRequest function, here's the snippet i'm using to get rid of the Cannot read property 'jquery' of undefined error:

快速调整——对于那些在transformRequest函数的全局配置上有问题的人,下面是我用来消除“无法读取”属性“jquery”的未定义错误的代码片段:

$httpProvider.defaults.transformRequest = function(data) {
        return data != undefined ? $.param(data) : null;
    }

#11


1  

You can also solve this problem without changing code in server, changing header in $http.post call and use $_POST the regular way. Explained here: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

您还可以解决这个问题,而无需更改服务器中的代码,只需更改$http中的头。按常规方式调用和使用$_POST。解释:http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

#12


0  

I found many times problematic behavior of this whole. I used it from express (without typings) and the bodyParser (with the dt~body-parser typings).

我发现这个整体有很多问题。我从express(没有排版)和bodyParser(使用dt~body-parser排版)中使用它。

I didn't try to upload a file, instead simply to interpret a JSON given in a post string.

我没有尝试上传一个文件,而是简单地解释一个post字符串中给出的JSON。

The request.body was simply an empty json ({}).

请求。body只是一个空的json({})。

After a lot of investigation finally this worked for me:

经过大量的调查,这对我来说很有效:

import { json } from 'body-parser';
...
app.use(json()); <-- should be defined before the first POST handler!

It may be also important to give the application/json content type in the request string from the client side.

在客户端请求字符串中提供应用程序/json内容类型也很重要。