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()
等)交换是非常混淆的。区别在于jQuery和AngularJS如何序列化和传输数据。 从根本上说,问题在于你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客户端部分和服务器部分。 所以你需要:
-
把js这样的angular客户端部分:
$http({ method: 'POST', url: 'request-url', data: {'message': 'Hello world'} });
和
-
写在你的服务器部分接收来自客户端的数据(如果是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=" + message
, data: $.param({message:message})
build立在@ felipe-miosso的答案:
- 从这里下载它作为AngularJS模块,
- 安装它
-
将其添加到您的应用程序:
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方法发送数据到服务器的完整的代码片段,以及为什么它在这种情况下不起作用。
下面的代码片段的解释…
- 我正在使用jQuery $ .param函数将JSON数据序列化到www post数据
-
在configurationvariables中设置Content-Type,该variables将与angularJS $ http.post的请求一起传递,指示服务器我们以www post格式发送数据。
-
注意$ 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¶m2=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服务的默认行为
- 添加标题
- 序列化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' } });