Angular $ http附加数据作为对象

时间:2015-04-16 11:26:42

标签: javascript angularjs angularjs-http

我试图通过angularjs从soundcloud API获取曲目列表 我试图发送的参数是:
1)client_id(字符串)
2)持续时间(具有两个属性的对象)。

以下是代码:

    var CLIENT_ID = 'a81f01ef5d0036415431e8be76c8db0e';
    var TRACKS_URL = 'https://api.soundcloud.com/tracks.json';

    var app = angular.module('soundcloud', []);

    app.controller('tracksController', function ($scope, $http) {

        $http({
            url: 'https://api.soundcloud.com/tracks.json',
            method: 'GET',
            data: {
                client_id: CLIENT_ID,
                duration: { // in milliseconds
                    from: 300000,
                    to: 400000
                }
            }
        })
            .success(function (data) {
                $scope.trackList = data;
            })
            .error(function () { alert('error'); });
    });

当我在浏览器的调试器中检查请求时,根本无法识别这些参数。

我试图使用' params'而不是数据',但这样就可以改变'持续时间'对象为json - >然后我得到状态500作为回应。
当我只在params发送client_id时,它工作正常,因为没有对象,只有字符串。

jQuery的ajax方法运行正常:https://jsfiddle.net/oacwz1up/3/

我该怎么办?如何正常发送参数?
请帮忙!谢谢!

4 个答案:

答案 0 :(得分:7)

这是因为Angular以不同于JQuery的方式序列化请求参数。

Angular 1.4将解决此问题,在$http config对象(以及$httpProvider.defaults)上引入paramSerializer属性。这可以用于任意序列化请求参数(对于所有或特定请求)。

请注意,自v1.4.0-rc.0以来,此功能仅


除了默认的序列化程序(将对象转换为JSON字符串)之外,还有一个额外的内置序列化程序可以模拟JQuery的param()$httpParamSerializerJQLike

你可以像这样使用它:

$http.get(<API_URL>, {
  params: {...},
  paramSerializer: '$httpParamSerializerJQLike'
});

另请参阅此 short demo


如果您使用的是旧版Angular,则可以执行以下操作之一:

  1. 自己构建整个网址(包括查询字符串)(可能使用$http请求interceptor自动将此应用于所有请求。)

  2. 将params保持为 flat 格式,这将导致Angular按预期序列化它们:

    var REQ_PARAMS = {
      client_id: 'a81f01ef5d0036415431e8be76c8db0e',
      'duration[from]': 200000,
      'duration[to]': 205000
    };
    

答案 1 :(得分:1)

如果您查看$http documentation,则会根据请求应用$http.defaults.transformRequest的默认转换,并按照说明执行以下操作(如您所见):

  

如果请求配置对象的data属性包含对象,请将其序列化为JSON格式。

您需要做的是通过指定自己的transformRequest对象来覆盖此函数。

function appendTransform(defaults, transform) {

  // We can't guarantee that the default transformation is an array
  defaults = angular.isArray(defaults) ? defaults : [defaults];

  // Append the new transformation to the defaults
  return defaults.concat(transform);
}

  $http({
      url: '...',
      method: 'GET',
      transformResponse: appendTransform($http.defaults.transformResponse, function(value) {
        return doTransform(value);
      })
  });

您需要找到一种方法来获得与jQuery提供的语法相同的语法:

https://api.soundcloud.com/tracks.json?client_id=a81f01ef5d0036415431e8be76c8db0e&duration[from]=200000&duration[to]=205000

使用条件是一个对象并手动生成您的String。应该不难。

答案 2 :(得分:0)

这是一个奇怪的API - 我不知道他们为什么不做“duration_from”这样的事情而不是需要持续时间[来自] - 正如你所建议的那样你可以转换请求,但如果这只是一个你的也可以尝试使用[]的网址转义值对其进行硬编码:

 var dataToSend = {
     client_id: 'a81f01ef5d0036415431e8be76c8db0e',
     'duration%5Bfrom%5D': 200000,
     'duration%5Bto%5D': 205000
 }; 

答案 3 :(得分:0)

$http.get('http://api.soundcloud.com/tracks.json', {params:dataToSend});

params属性是以宁静的方式转换查询的方法。只需转换dataToSend对象中的数据,它就可以工作。

这是应该创建的网址:

https://api.soundcloud.com/tracks.json?client_id=a81f01ef5d0036415431e8be76c8db0e&duration%5Bfrom%5D=200000&duration%5Bto%5D=205000