Javascript AngularJS - $http.post 发送请求参数而不是 JSON 的任何方式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12190166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:21:46  来源:igfitidea点击:

AngularJS - Any way for $http.post to send request parameters instead of JSON?

javascriptjquerypostangularjs

提问by dnc253

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

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

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

requestDatais 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:

我正在将我们的东西转移到使用 Angular,我想用 $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 $.postsends 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.postto 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 发送?是的,我知道我可以自己从对象构造字符串,但我想知道 Angular 是否提供了任何开箱即用的功能。

回答by Gloopy

I think the paramsconfig 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 paramas an example to convert the data to param string).

我认为paramsconfig 参数在这里不起作用,因为它将字符串添加到 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 $.postcall.

这样,所有对 $http.post 的调用都会自动将主体转换为 jQuery$.post调用使用的相同参数格式。

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

请注意,您可能还想为每个调用或全局设置 Content-Type 标头,如下所示:

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

回答by Saeb Amini

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

如果使用Angular >= 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=value2and send it to /requesturlwith the application/x-www-form-urlencoded; charset=utf-8Content-Type header as it's normally expected with POST requests on endpoints.

并且它将正确序列化数据param1=value1&param2=value2并将其/requesturlapplication/x-www-form-urlencoded; charset=utf-8Content-Type 标头一起发送到端点上的 POST 请求通常是预期的。

回答by Infeligo

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.

params – {Object.} – 将在 url 之后转换为 ?key1=value1&key2=value2 的字符串或对象的映射。如果值不是 string,它将被 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 的 $httpProvider.defaults.transformRequest 和 $httpProvider.defaults.transformResponse 属性。

Refer to documentationfor more details.

有关更多详细信息,请参阅文档

回答by Sagar Bhosale

Use jQuery's $.paramfunction 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。

回答by Thomas Graziani

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

请注意,从 Angular 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
});

回答by Frank Marcelo

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 天时间才弄明白这一点。

回答by TimoSolo

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

回答by Zags

Modify the default headers:

修改默认标题:

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

Then use JQuery's $.parammethod:

然后使用JQuery的$.param方法:

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

回答by Rohit Luthra

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

回答by kshep92

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 undefinederror:

快速调整 - 对于那些在 transformRequest 函数的全局配置中遇到问题的人,这里是我用来消除Cannot read property 'jquery' of undefined错误的代码片段:

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