如何在没有jQuery的情况下使用$ http发布urlencoded表单数据?

时间:2014-07-12 06:58:39

标签: javascript jquery angularjs ajax angularjs-http

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

这是有效的,但它也在$.param使用jQuery。为了消除对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会提供这个功能,但是如何?

11 个答案:

答案 0 :(得分:401)

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

From Ben Nadel's blog

  

默认情况下,$ http服务将转换传出请求   将数据序列化为JSON,然后将其与内容一起发布 -   类型," application / json"。当我们想要将值作为FORM发布时   发布后,我们需要更改序列化算法并发布数据   使用内容类型" application / x-www-form-urlencoded"。

示例from here

$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添加的新服务,请参阅

答案 1 :(得分:136)

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

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

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

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

  3. 使用示例

    $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 */ });
    

    See a more verbose Plunker demo

    $httpParamSerializerJQLike$httpParamSerializer如何不同

    一般来说,在涉及复杂的数据结构时,似乎$httpParamSerializer使用的“传统”网址编码格式比$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
    

答案 2 :(得分:56)

所有这些看起来都是矫枉过正(或者不工作)......就这样做:

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

答案 3 :(得分:21)

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

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

答案 4 :(得分:3)

这是应该的方式(并且请不要后端更改......当然不是......如果你的前堆栈不支持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)时使用promises $http,忘记.sucess.error回调(因为它们已被弃用)

  • 来自angularjs网站here您不能再使用JSON_CALLBACK字符串作为占位符来指定回调参数值应该去的位置。

    < / LI>

如果您的数据模型更复杂,只有用户名和密码,您仍然可以这样做(如上所述)

$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的文档here

答案 5 :(得分:2)

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

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

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

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

答案 6 :(得分:1)

$http文档开始,这应该有效..

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

答案 7 :(得分: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作为后端,那么你需要做一些修改.. checkout this link用于修复php服务器端

答案 8 :(得分:1)

虽然回答很晚,但我发现角度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();

答案 9 :(得分:1)

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

答案 10 :(得分:0)

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

这是我的角度控制器。

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
  data JSON_CALLBACK({“username”:“Victoria”,“password”:“password”,“callback”:“JSON_CALLBACK”});   httpTesting.js:18个头函数(c){a ||(a = sc(b)); return   下的[K(C)] ||空:一个}

有一个名为postman的chrome扩展名。您可以使用它来测试您的后端URL是否正常工作。 https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en

希望,我的回答可以帮到你。