197

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

我正在尝试使用$http我的 Angular 应用程序对服务器端进行 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);
});

这是有效的,但它也在$.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 会提供这个功能,但是怎么做呢?

4

11 回答 11

415

我认为您需要做的是将数据从对象转换为 JSON 字符串,而不是转换为 url 参数。

来自本纳德的博客

默认情况下,$http 服务将通过将数据序列化为 JSON,然后使用内容类型“application/json”发布它来转换传出请求。当我们想将值作为 FORM post 发布时,我们需要更改序列化算法并使用 content-type 发布数据,“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}
}).then(function () {});

更新

要使用 AngularJS V1.4 添加的新服务,请参阅

于 2014-07-25T21:19:41.103 回答
140

仅使用 AngularJS 服务的 URL 编码变量

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

  1. $httpParamSerializerJQLike- 受 jQuery 启发的序列化程序.param()推荐

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

$http() 示例

$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
  }
}).then(function(response) { /* do something here */ });

查看更详细的 Plunker 演示


$http.post() 示例

$http.post(
    'some/api/endpoint',
    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
      }
    }
).then(function

如何$httpParamSerializerJQLike$httpParamSerializer不同

一般来说,与复杂数据结构$httpParamSerializer相比,它似乎使用较少的“传统” url 编码格式。$httpParamSerializerJQLike

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

编码数组

{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
于 2015-06-21T23:11:17.957 回答
61

所有这些看起来都像是矫枉过正(或不起作用)......只需这样做:

$http.post(loginUrl, `username=${ encodeURIComponent(username) }` +
                     `&password=${ encodeURIComponent(password) }` +
                     '&grant_type=password'
).success(function (data) {
于 2015-03-24T09:16:09.030 回答
23

问题是 JSON 字符串格式,您可以在数据中使用简单的 URL 字符串:

$http({
    method: 'POST',
    url: url,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: 'username='+$scope.userName+'&password='+$scope.password
}).success(function () {});
于 2015-09-04T16:39:44.137 回答
4

这是它应该的方式(请不要更改后端......当然不是......如果你的前端堆栈不支持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 就像一个魅力

各位,给点建议吧:

  • .then(success, error)在处理$http,忘记.sucess和回调时使用承诺.error(因为它们已被弃用)

  • 这里的 angularjs 站点“您不能再使用 JSON_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可以在这里找到

于 2017-06-11T16:58:15.000 回答
3

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

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

如果它不是一个表单和一个简单的 json,那么试试这个标题:

headers[ "Content-type" ] = "application/json";
于 2014-07-15T07:35:11.720 回答
2

$http文档这应该可以工作..

  $http.post(url, data,{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
    .success(function(response) {
         // your code...
     });
于 2014-07-12T07:05:31.160 回答
2
$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);
});
于 2017-08-18T10:13:41.497 回答
1

你需要发布普通的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 服务器端

于 2014-07-27T09:28:33.297 回答
1

虽然答案较晚,但我发现 angular UrlSearchParams 对我来说效果很好,它也负责参数的编码。

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();
于 2017-03-24T13:27:07.187 回答
0

This worked for me. I use angular for front-end and laravel php for back-end. In my project, angular web sends json data to laravel back-end.

This is my angular controller.

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

});

This is my php back-end laravel controller.

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

This is my laravel routing

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

The result in browser is

status 200
data JSON_CALLBACK({"username":"Victoria","password":"password","callback":"JSON_CALLBACK"}); httpTesting.js:18 headers function (c){a||(a=sc(b));return c?a[K(c)]||null:a}

There is chrome extension called postman. You can use to test your back-end url whether it is working or not. https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en

hopefully, my answer will help you.

于 2014-07-29T05:11:51.240 回答