如何使用$ http POST urlencoded表单数据?

我是AngularJS的新手,一开始我想用AngularJS开发一个新的应用程序。

我正在尝试使用我的Angular App中的$http进行AJAX调用到服务器端。

为了发送参数,我尝试了以下内容:

 $http({ method: "post", url: URL, headers: {'Content-Type': 'application/x-www-form-urlencoded'}, data: $.param({username: $scope.userName, password: $scope.password}) }).success(function(result){ console.log(result); }); 

这是工作,但它也使用jQuery $.param 。 为了消除对jQuery的依赖,我试着:

 data: {username: $scope.userName, password: $scope.password} 

但这似乎失败了。 然后我尝试了params

 params: {username: $scope.userName, password: $scope.password} 

但这似乎也失败了。 然后我试着JSON.stringify

 data: JSON.stringify({username: $scope.userName, password: $scope.password}) 

我发现了这些可能的答案,但没有成功。 我做错了什么? 我相信,AngularJS会提供这个function,但是如何?

我想你需要做的是将你的数据从对象不是JSONstring,而是变为url params。

从Ben Nadel的博客 。

默认情况下,$ http服务将通过将数据序列化为JSON,然后将其与内容types“application / json”一起发送来转换传出的请求。 当我们想要将这个值作为一个FORMpost发布时,我们需要改变序列化algorithm,并将数据与内容types“application / x-www-form-urlencoded”一起发布。

从这里例子。

 $http({ method: 'POST', url: url, headers: {'Content-Type': 'application/x-www-form-urlencoded'}, transformRequest: function(obj) { var str = []; for(var p in obj) str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); return str.join("&"); }, data: {username: $scope.userName, password: $scope.password} }).success(function () {}); 

仅使用AngularJS服务的URL编码variables

使用AngularJS 1.4或更高版本,两个服务可以处理POST请求的url编码数据的过程,无需使用transformRequest或使用jQuery等外部依赖关系处理数据:

  1. $httpParamSerializerJQLike – 一个由jQuery的.param() 推荐的序列化器( 推荐

  2. $httpParamSerializer – Angular本身用于GET请求的序列化程序

用法示例

 $http({ url: 'some/api/endpoint', method: 'POST', data: $httpParamSerializerJQLike($scope.appForm.data), // Make sure to inject the service you choose to the controller headers: { 'Content-Type': 'application/x-www-form-urlencoded' // Note the appropriate header } }).success(function(response) { /* do something here */ }); 

查看更详细的Plunker演示


$httpParamSerializerJQLike$httpParamSerializer不同

一般来说,当涉及到复杂的数据结构时,似乎$httpParamSerializer使用比$httpParamSerializerJQLike更less的“传统”url编码格式。

例如(忽略括号的百分比编码):

编码一个数组

 {sites:['google', 'Facebook']} // Object with array property sites[]=google&sites[]=facebook // Result with $httpParamSerializerJQLike sites=google&sites=facebook // Result with $httpParamSerializer 

编码一个对象

 {address: {city: 'LA', country: 'USA'}} // Object with object property address[city]=LA&address[country]=USA // Result with $httpParamSerializerJQLike address={"city": "LA", country: "USA"} // Result with $httpParamSerializer 

所有这些看起来像矫枉过正(或不工作)…只是这样做:

 $http.post(loginUrl, "userName=" + encodeURIComponent(email) + "&password=" + encodeURIComponent(password) + "&grant_type=password" ).success(function (data) { 

问题是JSONstring格式,你可以在数据中使用一个简单的URLstring:

 $http({ method: 'POST', url: url, headers: {'Content-Type': 'application/x-www-form-urlencoded'}, data: 'username='+$scope.userName+'&password='+$scope.password }).success(function () {}); 

这是应该的方式(请不要后端更改…当然不是…如果你的前端堆栈不支持application/x-www-form-urlencoded ,然后把它扔掉…希望AngularJS呢!

 $http({ method: 'POST', url: 'api_endpoint', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, data: 'username='+$scope.username+'&password='+$scope.password }).then(function(response) { // on success }, function(response) { // on error }); 

像AngularJS 1.5一样的魅力

人们,让我给你一些build议:

  • 使用promise。然后.then(success, error)处理$http ,忘记.sucess.errorcallback(因为它们被弃用)

  • 从这里的angularjs站点“ 你不能再使用JSON_CALLBACKstring作为占位符来指定callback参数值应该去的地方”。

如果你的数据模型比较复杂,只是一个用户名和一个密码,你仍然可以这样做(如上所述)

 $http({ method: 'POST', url: 'api_endpoint', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, data: json_formatted_data, transformRequest: function(data, headers) { return transform_json_to_urlcoded(data); // iterate over fields and chain key=value separated with &, using encodeURIComponent javascript function } }).then(function(response) { // on succes }, function(response) { // on error }); 

encodeURIComponent文档可以在这里find

如果是表单,请尝试将标题更改为:

 headers[ "Content-type" ] = "application/x-www-form-urlencoded; charset=utf-8"; 

如果它不是一个forms和一个简单的JSON然后尝试这个头:

 headers[ "Content-type" ] = "application/json"; 

你需要发布纯JavaScript对象,没有别的

  var request = $http({ method: "post", url: "process.cfm", transformRequest: transformRequestAsFormPost, data: { id: 4, name: "Kim" } }); request.success( function( data ) { $scope.localData = data; } ); 

如果你有php作为后端,那么你将需要做一些更多的修改..检查此链接修复PHP服务器端

 $http({ method: "POST", url: "/server.php", headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: "name='Олег'&age='28'", }).success(function(data, status) { console.log(data); console.log(status); }); 

这对我有效。 我使用angular的前端和laravel PHP的后端。 在我的项目中,angular web将json数据发送到laravel后端。

这是我的angular度控制器。

 var angularJsApp= angular.module('angularJsApp',[]); angularJsApp.controller('MainCtrl', function ($scope ,$http) { $scope.userName ="Victoria"; $scope.password ="password" $http({ method :'POST', url:'http://api.mywebsite.com.localhost/httpTest?callback=JSON_CALLBACK', data: { username : $scope.userName , password: $scope.password}, headers: {'Content-Type': 'application/json'} }).success(function (data, status, headers, config) { console.log('status',status); console.log('data',status); console.log('headers',status); }); }); 

这是我的PHP后端laravel控制器。

 public function httpTest(){ if (Input::has('username')) { $user =Input::all(); return Response::json($user)->setCallback(Input::get('callback')); } } 

这是我的laravel路由

 Route::post('httpTest','HttpTestController@httpTest'); 

在浏览器中的结果是

状态200
数据JSON_CALLBACK({“用户名”:“维多利亚”,“密码”:“密码”,“callback”:“JSON_CALLBACK”}); httpTesting.js:18个头函数(c){a ||(a = sc(b)); return c?a [K(c)] || null:a}

有称为邮递员的铬扩展。 您可以使用来testing您的后端url,无论它是否工作。 https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en

希望我的回答能帮助你。

虽然一个迟到的答案,我发现angularUrlSearchParams工作得很好,它也照顾参数的编码。

 let params = new URLSearchParams(); params.set("abc", "def"); let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded'}); let options = new RequestOptions({ headers: headers, withCredentials: true }); this.http .post(UrlUtil.getOptionSubmitUrl(parentSubcatId), params, options) .catch(); 

从$ http文件这应该工作..

  $http.post(url, data,{headers: {'Content-Type': 'application/x-www-form-urlencoded'}}) .success(function(response) { // your code... });