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.262Z
(toISOString()
和 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
并编写我们自己的序列化程序。
就使用通用方法而言,第二种方法对我来说看起来更清晰。不过,我仍在寻找更好的选择。
我正在尝试使用 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.262Z
(toISOString()
和 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
并编写我们自己的序列化程序。
就使用通用方法而言,第二种方法对我来说看起来更清晰。不过,我仍在寻找更好的选择。