AngularJs $ http.post()不发送数据

任何人都可以告诉我为什么以下声明不发送发布数据到指定的url? URL被调用,但在服务器上,当我打印$ _POST – 我得到一个空的数组。 如果我在控制台中打印消息,然后将其添加到数据 – 它显示正确的内容。

$http.post('request-url', { 'message' : message }); 

我也试着用数据作为string(具有相同的结果):

 $http.post('request-url', "message=" + message); 

当我以下列格式使用它时,它似乎正在工作:

 $http({ method: 'POST', url: 'request-url', data: "message=" + message, headers: {'Content-Type': 'application/x-www-form-urlencoded'} }); 

但有没有办法做到这一点$ http.post() – 我总是必须包括头为了它的工作? 我相信上面的内容types是指定发送数据的格式,但是我可以把它作为javascript对象发送吗?

我有使用asp.net MVC相同的问题,并find了解决办法在这里

AngularJS的新手之间对于$http服务速记函数( $http.post()等)为什么似乎不能与jQuery等价物( jQuery.post()等)交换是非常混淆的。

区别在于jQueryAngularJS如何序列化和传输数据。 从根本上说,问题在于你select的服务器语言本身不能理解AngularJS的传输…默认情况下, jQuery使用

 Content-Type: x-www-form-urlencoded 

和熟悉的foo=bar&baz=moe序列化。

然而, AngularJS使用传输数据

 Content-Type: application/json 

{ "foo": "bar", "baz": "moe" }

JSON序列化,不幸的是一些Web服务器语言 – 特别是PHP –本身并不反序列化。

奇迹般有效。

 // Your app's root module... angular.module('MyModule', [], function($httpProvider) { // Use x-www-form-urlencoded Content-Type $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; /** * The workhorse; converts an object to x-www-form-urlencoded serialization. * @param {Object} obj * @return {String} */ var param = function(obj) { var query = '', name, value, fullSubName, subName, subValue, innerObj, i; for(name in obj) { value = obj[name]; if(value instanceof Array) { for(i=0; i<value.length; ++i) { subValue = value[i]; fullSubName = name + '[' + i + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += param(innerObj) + '&'; } } else if(value instanceof Object) { for(subName in value) { subValue = value[subName]; fullSubName = name + '[' + subName + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += param(innerObj) + '&'; } } else if(value !== undefined && value !== null) query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; } return query.length ? query.substr(0, query.length - 1) : query; }; // Override $http service's default transformRequest $httpProvider.defaults.transformRequest = [function(data) { return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data; }]; }); 

上面不是很清楚,但是如果你在PHP中接收请求,你可以使用:

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

从AngularJS POST中访问PHP中的数组。

您可以像这样设置默认的“Content-Type”:

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

关于data格式:

$ http.post和$ http.put方法接受任何JavaScript对象(或string)值作为其数据参数。 如果数据是JavaScript对象,则默认情况下,它将转换为JSONstring。

尝试使用这种变化

 function sendData($scope) { $http({ url: 'request-url', method: "POST", data: { 'message' : message } }) .then(function(response) { // success }, function(response) { // optional // failed }); } 

我有一个类似的问题,我不知道这是否也可以是有用的: https : //stackoverflow.com/a/11443066

 var xsrf = $.param({fkey: "key"}); $http({ method: 'POST', url: url, data: xsrf, headers: {'Content-Type': 'application/x-www-form-urlencoded'} }) 

问候,

我喜欢使用一个函数来转换对象来传递参数。

 myobject = {'one':'1','two':'2','three':'3'} Object.toparams = function ObjecttoParams(obj) { var p = []; for (var key in obj) { p.push(key + '=' + encodeURIComponent(obj[key])); } return p.join('&'); }; $http({ method: 'POST', url: url, data: Object.toparams(myobject), headers: {'Content-Type': 'application/x-www-form-urlencoded'} }) 

这终于在使用$ httpParamSerializerJQLike的angular1.4中解决了

请参阅https://github.com/angular/angular.js/issues/6039

 .controller('myCtrl', function($http, $httpParamSerializerJQLike) { $http({ method: 'POST', url: baseUrl, data: $httpParamSerializerJQLike({ "user":{ "email":"wahxxx@gmail.com", "password":"123456" } }), headers: 'Content-Type': 'application/x-www-form-urlencoded' })}) 

我使用jQuery param和AngularJS post requrest。 下面是一个例子…创buildAngularJS应用程序模块,其中myapp是用HTML代码中的ng-app定义的。

 var app = angular.module('myapp', []); 

现在让我们创build一个login控制器和POST电子邮件和密码。

 app.controller('LoginController', ['$scope', '$http', function ($scope, $http) { // default post header $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; // send login data $http({ method: 'POST', url: 'https://example.com/user/login', data: $.param({ email: $scope.email, password: $scope.password }), headers: {'Content-Type': 'application/x-www-form-urlencoded'} }).success(function (data, status, headers, config) { // handle success things }).error(function (data, status, headers, config) { // handle error things }); }]); 

我不喜欢exaplain的代码,这是很容易理解:)请注意, param是从jQuery,所以你必须安装jQuery和AngularJS使其工作。 这是一个截图。

在这里输入图像描述

希望这是有帮助的。 谢谢!

与JQuery不同的是,Angular使用JSON格式将POST数据从客户端传输到服务器(据推测,JQuery应用x-www-form-urlencoded,尽pipeJQuery和Angular使用JSON来处理数据)。 因此,问题有两个部分:在js客户端部分和服务器部分。 所以你需要:

  1. 把js这样的angular客户端部分:

     $http({ method: 'POST', url: 'request-url', data: {'message': 'Hello world'} }); 

  1. 写在你的服务器部分接收来自客户端的数据(如果是PHP)。

      $data = file_get_contents("php://input"); $dataJsonDecode = json_decode($data); $message = $dataJsonDecode->message; echo $message; //'Hello world' 

注意:$ _POST不起作用!

该解决scheme对我来说很好,希望和你。

我与AngularJS和Node.js + Express 4 + Router有同样的问题

路由器期望正文中的请求数据。 如果我遵循Angular Docs的例子,这个机构总是空的

符号1

 $http.post('/someUrl', {msg:'hello word!'}) 

但是,如果我在数据中使用它

符号2

 $http({ withCredentials: false, method: 'post', url: yourUrl, headers: {'Content-Type': 'application/x-www-form-urlencoded'}, data: postData }); 

编辑1:

否则,node.js路由器将使用符号1期望req.body中的数据:

 req.body.msg 

其中也发送信息作为JSON有效载荷。 这在一些情况下更好,在你的json中有数组,而x-www-form-urlencoded会给出一些问题。

有效。 希望它有帮助。

要通过post方法发送数据到$http of angularjs,你需要改变

data: "message=" + messagedata: $.param({message:message})

build立在@ felipe-miosso的答案:

  1. 从这里下载它作为AngularJS模块,
  2. 安装它
  3. 将其添加到您的应用程序:

     var app = angular.module('my_app', [ ... , 'httpPostFix']); 

这段代码为我解决了这个问题。 这是一个应用程序级别的解决scheme:

 moduleName.config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.transformRequest.push(function(data) { var requestStr; if (data) { data = JSON.parse(data); for (var key in data) { if (requestStr) { requestStr += "&" + key + "=" + data[key]; } else { requestStr = key + "=" + data[key]; } } } return requestStr; }); $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; } ]); 

我没有评论的声望,但作为回应/除了唐F的答案:

$params = json_decode(file_get_contents('php://input'));

true的第二个参数需要被添加到json_decode函数中,以正确地返回关联数组:

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

angular

  var payload = $.param({ jobId: 2 }); this.$http({ method: 'POST', url: 'web/api/ResourceAction/processfile', data: payload, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); 

WebAPI 2

 public class AcceptJobParams { public int jobId { get; set; } } public IHttpActionResult ProcessFile([FromBody]AcceptJobParams thing) { // do something with fileName parameter return Ok(); } 

把这个添加到你的js文件中:

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

并将其添加到您的服务器文件中:

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

这应该工作。

这可能是一个迟到的答案,但我认为最正确的方法是使用相同的一段代码angular度使用时,使用您的“get”请求$httpParamSerializer将不得不将其注入到您的控制器,所以你可以简单地做到以下没有必须使用$http.post(url,$httpParamSerializer({param:val}))$http.post(url,$httpParamSerializer({param:val}))

 app.controller('ctrl',function($scope,$http,$httpParamSerializer){ $http.post(url,$httpParamSerializer({param:val,secondParam:secondVal})); } 

我知道已经接受了答案。 但是,以下可能有助于未来的读者,如果答案不适合他们出于任何原因。

Angular不会像jQuery那样做ajax。 虽然我试图按照指导修改angular度$httpprovider ,我遇到了其他问题。 例如我使用codeigniter其中$this->input->is_ajax_request()函数总是失败(这是由另一个程序员写的,全球使用,所以不能改变),说这不是真正的Ajax请求。

为了解决这个问题,我借助了延期承诺 。 我在Firefox中testing它,ie9和它的工作。

我有任何angular码以外定义以下function。 这个函数定期jquery ajax调用并返回deferred / promise(我还在学习)对象。

 function getjQueryAjax(url, obj){ return $.ajax({ type: 'post', url: url, cache: true, data: obj }); } 

然后我使用下面的代码将其称为angular码。 请注意,我们必须手动更新$scope ,使用$scope.$apply()

  var data = { media: "video", scope: "movies" }; var rPromise = getjQueryAjax("myController/getMeTypes" , data); rPromise.success(function(response){ console.log(response); $scope.$apply(function(){ $scope.testData = JSON.parse(response); console.log($scope.testData); }); }).error(function(){ console.log("AJAX failed!"); }); 

这可能不是完美的答案,但它允许我使用angular度jQuery的Ajax调用,并允许我更新$scope

我也面临类似的问题,我正在做这样的事情,并没有奏效。 我的Spring控制器无法读取数据参数。

 var paramsVal={data:'"id":"1"'}; $http.post("Request URL", {params: paramsVal}); 

但是阅读这个论坛和API Doc,我尝试了下面的方式,并为我工作。 如果有人也有类似的问题,你也可以尝试下面的方法。

 $http({ method: 'POST', url: "Request URL", params: paramsVal, headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'} }); 

请查看https://docs.angularjs.org/api/ng/service/ $ http#post以了解param config的function。 {data:'“id”:“1”'} – 将转换为URL的string或对象的映射?data =“id:1”

我正在使用angularjs和下面的代码工作的asp.net WCF webservices:

  $http({ contentType: "application/json; charset=utf-8",//required method: "POST", url: '../../operation/Service.svc/user_forget', dataType: "json",//optional data:{ "uid_or_phone": $scope.forgettel, "user_email": $scope.forgetemail }, async: "isAsync"//optional }).success( function (response) { $scope.userforgeterror = response.d; }) 

希望它有帮助。

没有find如何使用$ http.post方法发送数据到服务器的完整的代码片段,以及为什么它在这种情况下不起作用。

下面的代码片段的解释…

  1. 我正在使用jQuery $ .param函数将JSON数据序列化到www post数据
  2. 在configurationvariables中设置Content-Type,该variables将与angularJS $ http.post的请求一起传递,指示服务器我们以www post格式发送数据。

  3. 注意$ htttp.post方法,我发送第一个参数为url,第二个参数为数据(序列化),第三个参数为config。

剩余的代码是自我理解的。

 $scope.SendData = function () { // use $.param jQuery function to serialize data from JSON var data = $.param({ fName: $scope.firstName, lName: $scope.lastName }); var config = { headers : { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;' } } $http.post('/ServerRequest/PostDataResponse', data, config) .success(function (data, status, headers, config) { $scope.PostDataResponse = data; }) .error(function (data, status, header, config) { $scope.ResponseDetails = "Data: " + data + "<hr />status: " + status + "<hr />headers: " + header + "<hr />config: " + config; }); }; 

看看这里的$ http.post方法的代码示例。

如果使用Angular> = 1.4 ,则使用Angular 提供的序列化程序 ,这是最干净的解决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请求。

TL; DR

在我的研究中,我发现这个问题的答案有很多不同的方面。 有些是非常复杂的,取决于自定义函数,一些依赖于jQuery和一些不完整的提示你只需要设置标题。

如果只设置了Content-Type头,终点将会看到POST数据,但是它不会是标准格式,因为除非你提供一个string作为你的data ,或者手动序列化你的数据对象,它将全部是序列化为默认的JSON,并可能在端点上被错误地解释。

例如,如果在上面的例子中没有设置正确的串行器,那么在端点中将会看到:

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

这可能会导致意想不到的parsing,例如ASP.NET把它当作一个null参数名称,用{"param1":"value1","param2":"value2"}作为值; 或Fiddler以另一种方式解释它,以{"param1":"value1","param2":"value2"}作为参数名称, null

当我有这个问题时,我发布的参数竟然是一个对象数组,而不是一个简单的对象。

我有同样的问题expression..解决你必须使用bodyparserparsingjson对象之前发送http请求..

 app.use(bodyParser.json()); 

刚刚从angular度1.2更新到1.3,在代码中发现了一个问题。 转换资源将导致无限循环,因为(我认为)$ promise再次持有同一个对象。 也许它会帮助别人…

我可以解决这个问题:

 [...] /** * The workhorse; converts an object to x-www-form-urlencoded serialization. * @param {Object} obj * @return {String} */ var param = function (obj) { var query = '', name, value, fullSubName, subName, subValue, innerObj, i; angular.forEach(obj, function(value, name) { + if(name.indexOf("$promise") != -1) { + return; + } value = obj[name]; if (value instanceof Array) { for (i = 0; i < value.length; ++i) { [...] 

我一直在使用接受的答案代码(菲利普的代码)一段时间,它一直在努力(谢谢,菲利普!)。

然而,最近我发现它有空对象或数组的问题。 例如,提交此对象时:

 { A: 1, B: { a: [ ], }, C: [ ], D: "2" } 

PHP似乎没有看到B和C. 它得到这个:

 [ "A" => "1", "B" => "2" ] 

在Chrome浏览器的实际请求显示了这一点:

 A: 1 : D: 2 

我写了一个替代的代码片段。 这似乎与我的使用情况很好,但我还没有广泛的testing,所以谨慎使用。

我使用了TypeScript,因为我喜欢强壮的打字,但是很容易转换成纯JS:

 angular.module("MyModule").config([ "$httpProvider", function($httpProvider: ng.IHttpProvider) { // Use x-www-form-urlencoded Content-Type $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8"; function phpize(obj: Object | any[], depth: number = 1): string[] { var arr: string[] = [ ]; angular.forEach(obj, (value: any, key: string) => { if (angular.isObject(value) || angular.isArray(value)) { var arrInner: string[] = phpize(value, depth + 1); var tmpKey: string; var encodedKey = encodeURIComponent(key); if (depth == 1) tmpKey = encodedKey; else tmpKey = `[${encodedKey}]`; if (arrInner.length == 0) { arr.push(`${tmpKey}=`); } else { arr = arr.concat(arrInner.map(inner => `${tmpKey}${inner}`)); } } else { var encodedKey = encodeURIComponent(key); var encodedValue; if (angular.isUndefined(value) || value === null) encodedValue = ""; else encodedValue = encodeURIComponent(value); if (depth == 1) { arr.push(`${encodedKey}=${encodedValue}`); } else { arr.push(`[${encodedKey}]=${encodedValue}`); } } }); return arr; } // Override $http service's default transformRequest (<any>$httpProvider.defaults).transformRequest = [ function(data: any) { if (!angular.isObject(data) || data.toString() == "[object File]") return data; return phpize(data).join("&"); } ]; } ]); 

它的效率比Felipe的代码低,但我认为这不重要,因为它应该是直接相比,HTTP请求本身的总开销。

现在PHP显示:

 [ "A" => "1", "B" => [ "a" => "" ], "C" => "", "D" => "2" ] 

据我所知,不可能让PHP认识到Ba和C是空的数组,但是至less会出现这些键,当有一些代码依赖于某个结构,即使它本质上是空的时,这也是非常重要的。

另请注意,它将未定义的 s和 s转换为空string。

如果你使用PHP这是一个简单的方法来从AngularJS POST访问PHP中的数组。

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

在我的情况下,我解决了这样的问题:

 var deferred = $q.defer(); $http({ method: 'POST', url: 'myUri', data: $.param({ param1: 'blablabla', param2: JSON.stringify(objJSON) }), headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).then( function(res) { console.log('succes !', res.data); deferred.resolve(res.data); }, function(err) { console.log('error...', err); deferred.resolve(err); } ); return deferred.promise; 

您需要为包含JSON对象的每个参数使用JSON.stringify,然后使用“$ .param”构build您的数据对象:-)

注意:我的“objJSON”是一个包含数组,整数,string和html内容的JSON对象。 他的总大小是> 3500个字符。

我用下面的代码解决了这个问题

客户端(Js):

  $http({ url: me.serverPath, method: 'POST', data: data, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, }). success(function (serverData) { console.log("ServerData:", serverData); ...... 

注意到数据是一个对象。

在服务器上(ASP.NET MVC):

 [AllowCrossSiteJson] public string Api() { var data = JsonConvert.DeserializeObject<AgentRequest>(Request.Form[0]); if (data == null) return "Null Request"; var bl = Page.Bl = new Core(this); return data.methodName; } 

并且跨域请求需要“AllowCrossSiteJsonAttribute”:

 public class AllowCrossSiteJsonAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*"); base.OnActionExecuting(filterContext); } } 

希望这是有用的。

这不是angular度的错。 Angular被devise为在JSON世界中工作。 所以当$ http服务发送AJAX请求时,它会将所有数据作为有效负载发送,而不是作为表单数据发送,以便后端应用程序可以处理它。 但jQuery在内部做了一些事情。 您可以指示jQuery的$ ajax模块将表单数据绑定为JSON,但在发送AJAX请求之前,它会序列化JSON并添加application/x-www-form-urlencoded标头。 这样,后端应用程序就能以post参数的forms接收表单数据,而不是JSON。

但是你可以通过修改$ http服务的默认行为

  1. 添加标题
  2. 序列化json

$ httpParamSerializerJQLike是angular的内置服务,它以与jQuery相同的方式序列化json。

 $http({ method: 'POST', url: 'request-url', data: $httpParamSerializerJQLike(json-form-data), headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;' } }); 

如果你需要一个插件来首先将表单数据序列化成JSON,使用这个https://github.com/marioizquierdo/jquery.serializeJSON

类似于OP的build议的工作格式和Denison的答案,除了使用$http.post而不是$http ,仍然依赖于jQuery。

这里使用jQuery的好处是复杂的对象可以正确地传递。 反对手工转换成可能造成数据窜改的URL参数。

 $http.post( 'request-url', jQuery.param( { 'message': message } ), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });