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

AngularJS $http GET comma separated query string parameters

我正在尝试使用 Angular 的 $http 进行 HTTP GET 调用。我写了一个像这样的通用函数,

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

我想创建一个这样的 URL, 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 字段的目的吗?

好的,对于那些和我遇到同样问题的人,我找到了两种解决方法。

首先,正如@kiro112 在评论中建议的那样,我直接将参数写在URL 中。由于 $http 不对 URL 进行编码,因此它会起作用。所以代码会是这样的

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

而且我们必须删除 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));
        }
      });
    }

这里发生的是,我们不让 angular 对参数进行编码。让我来告诉你为什么。根据 docs here,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 并编写我们自己的序列化程序。

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