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

IT技术 javascript jquery angularjs ajax angularjs-http
2021-01-23 09:44:29

我是 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 会提供这个功能,但是如何呢?

6个回答

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

来自 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 () {});

更新

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

如果我需要提交多部分/表单数据怎么办?
2021-03-15 09:44:29
只要angular下嵌入jqLit​​e angular.element,就可以简单的return angular.element.param(obj);
2021-03-16 09:44:29
感谢您不使用 JQuery!
2021-03-22 09:44:29
这是另一种方式 var obj = {a: 1, b: 2}; Object.keys(obj).reduce(function(p, c) { return p.concat([encodeURIComponent(c) + "=" + encodeURIComponent(obj[c])]); }, []).join('&');
2021-03-22 09:44:29
@Vicary 请记住,param() 未在 jqLit​​e 中实现 - code.angularjs.org/1.3.14/docs/api/ng/function/angular.element
2021-03-25 09:44:29

仅使用 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
从 jQuery 迁移到 AngularJS 后,这非常有效
2021-03-14 09:44:29
应该$http.({...代替`$http.post({...
2021-03-15 09:44:29
这是我正在寻找的特定于 AngularJS 的答案。我希望发帖人将其选为最佳答案。
2021-03-17 09:44:29
我们如何在工厂内的 $resource 上使用它?
2021-03-30 09:44:29
@CarlosGranados 感谢您的关注。在此处和 Plunker 演示中更正了此错字。
2021-04-06 09:44:29

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

$http.post(loginUrl, `username=${ encodeURIComponent(username) }` +
                     `&password=${ encodeURIComponent(password) }` +
                     '&grant_type=password'
).success(function (data) {
终于有点常识了
2021-03-11 09:44:29
这不会发送带有错误内容类型标头的请求吗?
2021-03-14 09:44:29
它对我有用......不确定标头是什么,但请求有效并且允许成功进行身份验证。你为什么不测试一下并告诉我们。
2021-03-17 09:44:29
@Phil 我想这可能取决于服务器,我收到了错误的请求,直到我添加了 { headers: {'Content-Type': 'application/x-www-form-urlencoded'} } 作为配置参数,或者提供使用$http(config) 构造函数就像 moices 的答案所示。无论哪种方式,这都优于公认的答案,因为它不会引入一些神奇的转换,也不需要用户使用某些辅助服务。谢谢!
2021-03-19 09:44:29

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

$http({
    method: 'POST',
    url: url,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: 'username='+$scope.userName+'&password='+$scope.password
}).success(function () {});
这是唯一对我有用的答案!我跳过成功,但 $http 格式很好
2021-03-28 09:44:29
您必须使用encodeURIComponent($scope.userName)对数据进行 url 编码,否则如果用户输入类似的值,您的参数将被损坏"&myCustomParam=1"
2021-04-09 09:44:29

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

  • 这里的 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可以在此处找到文档