AngularJS – 任何方式为$ http.post发送请求参数,而不是JSON?

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

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

requestData只是一个具有一些基本string属性的JavaScript对象。

我正在把我们的东西转移到使用Angular的过程中,我想用$ http.postreplace这个调用。 我想出了以下几点:

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

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

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

成功的jQuery $.post像这样发送主体:

 param1=value1&param2=value2&param3=value3 

我正在打的端点是期望的请求参数,而不是JSON。 所以,我的问题是有无论如何告诉$http.post发送JavaScript对象作为请求参数,而不是JSON? 是的,我知道我可以从对象中自己构buildstring,但是我想知道Angular是否提供了任何开箱即用的function。

我认为paramsconfiguration参数在这里不起作用,因为它将string添加到url而不是body中,但是添加到Infeligo在这里提出的是一个默认转换的全局覆盖的例子(以jQuery param为例将数据转换为参数string)。

设置全局变换请求函数:

 var app = angular.module('myApp'); app.config(function ($httpProvider) { $httpProvider.defaults.transformRequest = function(data){ if (data === undefined) { return data; } return $.param(data); } }); 

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

请注意,您可能还需要设置每个呼叫的Content-Type标题或全局像这样的:

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

每次调用的非全局transformRequest示例:

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

如果使用Angular> = 1.4 ,这里是我发现的最干净的解决scheme,不依赖于任何自定义或外部:

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

然后你可以在你的应用程序的任何地方做这个:

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

它会正确地将数据序列化为param1=value1&param2=value2并通过application/x-www-form-urlencoded; charset=utf-8发送到/requesturl application/x-www-form-urlencoded; charset=utf-8 application/x-www-form-urlencoded; charset=utf-8 Content-Type头,因为通常在端点上使用POST请求。

从AngularJS文档:

params – {Object。} – string或对象的映射将被转换为?key1 = value1&key2 = value2之后的url。 如果该值不是一个string ,它将被JSON化。

所以,提供string作为参数。 如果你不想要,那么使用转换。 再次,从文档:

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

请参阅文档了解更多细节。

使用jQuery的$.param函数来序列化requestData中的JSON数据。

总之,使用类似的代码作为你的:

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

为了使用这个,你必须在你的页面中包含jQuery和AngularJS。

请注意,从Angular 1.4开始,您可以在不使用jQuery的情况下序列化表单数据。

在app.js中:

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

然后在你的控制器中:

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

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

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

我也有设置自定义http身份validation的问题,因为$资源caching请求。

要做到这一点,你必须重写现有的标题

 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'} }, } ); 

我希望我能帮助别人。 我花了三天的时间来弄清楚这一点。

修改默认标题:

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

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

 var payload = $.param({key: value}); $http.post(targetURL, payload); 
  .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 () {}); } ]); 

快速调整 – 对于那些遇到transformRequest函数的全局configuration有问题的人,这里是我用来摆脱Cannot read property 'jquery' of undefined错误的Cannot read property 'jquery' of undefined的代码片段:

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

你也可以在不改变服务器代码的情况下解决这个问题,在$http.post调用中改变头文件,并以常规的方式使用$_POST 。 在这里解释: http : //victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

我发现这个整体有许多次有问题的行为。 我用express(没有types)和bodyParser(用dt〜body-parsertypes)。

我没有尝试上传一个文件,而是简单地解释一个后置string中给出的JSON。

request.body只是一个空的json( {} )。

经过很多调查终于这对我工作:

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

从客户端提供请求string中的application/json内容types也是很重要的。

Interesting Posts