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

Vee*_*tav 191 javascript ajax jquery angularjs angularjs-http

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

我正在尝试使用$http我的Angular App 对服务器端进行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);
});
Run Code Online (Sandbox Code Playgroud)

这是有效的,但它也使用jQuery $.param.为了消除对jQuery的依赖,我尝试了:

data: {username: $scope.userName, password: $scope.password}
Run Code Online (Sandbox Code Playgroud)

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

params: {username: $scope.userName, password: $scope.password}
Run Code Online (Sandbox Code Playgroud)

但这似乎也失败了.然后我尝试了JSON.stringify:

data: JSON.stringify({username: $scope.userName, password: $scope.password})
Run Code Online (Sandbox Code Playgroud)

我找到了这些可能的答案,但没有成功.难道我做错了什么?我相信,AngularJS会提供这个功能,但是如何?

all*_*kim 406

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

来自Ben Nadel的博客.

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

UPDATE

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

  • 谢谢你没有使用JQuery! (40认同)
  • @Vicary请记住,jramLite中没有实现param() - https://code.angularjs.org/1.3.14/docs/api/ng/function/angular.element (4认同)
  • 只要角度嵌入`angular.element`下的jqLit​​e,你就可以简单地`返回angular.element.param(obj);` (2认同)

Boa*_*oaz 137

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

使用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
  }
}).then(function(response) { /* do something here */ });
Run Code Online (Sandbox Code Playgroud)

查看更详细的Plunker演示


怎么样$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
Run Code Online (Sandbox Code Playgroud)

编码对象

{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
Run Code Online (Sandbox Code Playgroud)

  • 这是我正在寻找的AngularJS特定的答案.我希望海报会选择这个作为最佳答案. (4认同)
  • 应该是`$ http.({...`而不是``$ http.post({...` (2认同)

Ser*_*gan 58

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

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

  • 最后有些常识 (10认同)
  • @Phil我想这可能取决于服务器,我得到了错误的请求,直到我添加{headers:{'Content-Type':'application/x-www-form-urlencoded'}}作为配置arg或供应使用像moices的答案显示的$ http(config)构造函数.无论哪种方式,这都优于已接受的答案,因为它没有引入一些魔术转换,也不需要某些辅助服务的用户.谢谢! (5认同)

小智 22

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

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

  • 您必须使用`encodeURIComponent($ scope.userName)`来对数据进行url编码,否则如果用户输入的值如"&myCustomParam = 1",则参数将被破坏 (7认同)
  • 这是唯一对我有用的答案!我跳过了成功,但$ http格式是好的 (2认同)