AngularJS $ http GET逗号分隔查询字符串参数

时间:2016-06-02 07:40:00

标签: angularjs http get google-drive-api query-parameters

我尝试使用Angular' $ http进行HTTP GET调用。我已经写了这样的通用函数,

function doGETRequest(url, params) {
      return $http({
        method: 'GET',
        url: baseURL + url,
        headers: {
          'Authorization': 'Bearer ' + access_token
        },
        params: params
      });
    }

我想创建一个这样的网址, https://content.googleapis.com/drive/v2/about?fields=quotaBytesTotal%2CquotaBytesUsed%2CrootFolderId%2Cuser但我不能为我的生活弄清楚查询参数部分。到目前为止,我尝试了以下内容:

 doGETRequest('/about', {fields:'user,quotaBytesTotal,quotaBytesUsed,rootFolderId'})


doGETRequest('/about', {fields:['user','quotaBytesTotal','quotaBytesUsed','rootFolderId']})


doGETRequest('/about', {fields:encodeURIComponent('user,quotaBytesTotal,quotaBytesUsed,rootFolderId')})

它适用于第二个,但它将其解析为https://content.googleapis.com/drive/v2/about?fields=user&fields=quotaBytesTotal&fields=quotaBytesUsed&fields=rootFolderId,Google只发送第一个查询的响应并忽略其余的(如预期的那样)。

所以问题是如何在查询参数中传递逗号分隔值?我是否必须手动编写URL编码值?这不是打败了一个params领域的目的吗?

1 个答案:

答案 0 :(得分:0)

好吧,对于那些偶然发现同样问题的人,我找到了解决这个问题的两种方法。

首先,正如@ kiro112在评论中建议的那样,我直接在URL中写了params。由于$ http不会对网址进行编码,因此它无法正常工作。所以代码就像

doGETRequest('/about?fields='+encodeURIComponent("user,quotaBytesTotal,quotaBytesUsed,rootFolderId"))

我们必须摆脱params方法中的doGetRequest()部分。就我个人而言,我不喜欢这个,因为它的目的是让params参与$ http。

第二个方法覆盖默认$httpParamSerializer并提供我们自己的。要做到这一点,doGetRequest()方法必须像这样修改,

function doGETRequest(url, params) {
      return $http({
        method: 'GET',
        url: baseURL + url,
        headers: {
          'Authorization': 'Bearer ' +access_token
        },
        params: params,
        paramSerializer: function (value){
          return Object.keys(value)+'='+encodeURIComponent(Object.values(value));
        }
      });
    }

这里发生的是,我们不会对params进行角度编码。让我来告诉你为什么。根据{{​​3}},angular只会像这样进行编码,

  • {'foo': 'bar'}会产生foo=bar
  • {'foo': Date.now()}会产生foo=2015-04-01T09%3A50%3A49.262ZtoISOString()和Date对象的编码表示形式)
  • {'foo': ['bar', 'baz']}会产生foo=bar&foo=baz(每个数组元素的重复键)
  • {'foo': {'bar':'baz'}}会生成foo=%7B%22bar%22%3A%22baz%22%7D"(对象的字符串化和编码表示)

虽然我们需要{'foo':['bar', 'baz']}行中的某些内容,但会产生foo=bar%2Cbaz。所以我们覆盖paramSerializer并编写我们自己的序列化器。

就使用通用方法而言,第二种方法对我来说看起来更清晰。但是,我仍在寻找更好的选择。