我有一种感觉我只是看错了,但我想通过Angular的$ http.get()方法获取有关传递URL查询参数的正确方法的反馈 - 特别是包含逗号的参数。
假设我有以下数据,可用作GET请求中的URL参数:
var params = {
filter : [
"My filter",
"My other filter",
"A filter, that contains, some commas"
],
sort : [
"ascending"
]
};
现在,我将此结构转换为可以输入$http.get
的一些参数:
var urlParams = {};
angular.forEach(params, function(value, name) {
urlParams[name] = "";
for (var i = 0; i < value.length; i++) {
urlParams[name] += value[i];
if (i < value.length - 1) {
urlParams[name] += ","
}
}
}
此时,urlParams
看起来像这样:
{
filter : "My filter,My other filter,A filter, that contains, some commas",
sort : "ascending"
}
现在,这不是我想要的,因为第三个filter
参数现在变成了三个独立的参数。 (我正在使用的API不允许以任何其他方式传递参数的多个值:“?param = value1,value2,value3”)所以,我需要做的是首先对URI编码这些值,对?所以,我在上面的例程中添加encodeURIComponent()
,如下所示:
urlParams[name] += encodeURIComponent(value[i]);
这给了我一个如下所示的参数对象:
{
filter : "My%20filter,My%20other%20filter,A%20filter%2C%20that%20contains%2C%20some%20commas",
sort : "ascending"
}
现在,我提出了一个请求:
var config = {
params : urlParams
};
$http.get("/foo", config).then(function(response){
console.log(response);
});
...这不起作用,因为Angular也对URL参数进行编码,因此请求最终看起来像这样:
GET "/foo?filter=My%2520filter,My%2520other%2520filter,A%2520filter%2C%20that%20contains%2C%20some%20commas&sort=ascending"
正如您所看到的那样,参数被编码两次(%符号被编码为%25),这当然不起作用。
显然,我做错了。但是正确的方法是什么?或者,我是否需要让API开发人员接受这样的URL参数?
GET "/foo?filter=My+filter,+with+a+comma&filter=Another+filter"
其中多个参数值是单独说明的,而不是逗号分隔?
答案 0 :(得分:5)
正如您所描述的那样,无法可靠地传递包含逗号的值。
假设您要将项目["one","two","three,four"]
作为列表传递。
如果按原样传递字符串,API将会看到(在正常的服务器端URL解码之后)
one,two,three,four
使three,four
与两个单独的项目无法区分。
如果您传递URL编码的字符串,整个参数将被双重编码,API将会看到(再次,在URL解码后)
one,two,three%2Cfour
现在参数 可以区分,但这需要API支持对每个项目进行单独的URL解码。
假设您传递了one,two,"three,four"
之类的字符串,即引用了包含逗号的项目。 API 可以正确解码参数,但它需要支持更复杂的语法(引用字符串),而不是简单地用逗号分割...
......等等。最重要的是,如果没有来自API的额外支持,我认为你不能做任何事情,客户端可以欺骗它来正确解码包含逗号的字符串。 是 API开发人员可以进行的许多调整,例如
POST
接受JSON编码的正文。您需要让API开发人员做某事。
答案 1 :(得分:1)
我认为你不应该使用逗号作为数组的分隔符。
我建议
或使用其他字符串作为分隔符。例如,@@@
。
仅供参考,你可以简单地将你的数组加入到像这样的字符串中。
array.join(',')
答案 2 :(得分:0)
来自$ http docs
如果您希望仅针对单个请求覆盖请求/响应转换,则在传递到$ http的配置对象上提供transformRequest和/或transformResponse属性。
请注意,如果在配置对象上提供这些属性,则将覆盖默认转换。如果您希望扩充默认转换,则必须将它们包含在本地转换数组中。
简而言之,您可以使用encodeURIComponent()
功能通过在每个请求的配置对象中包含transformRequest
属性来替换默认值,或者您可以建立全局覆盖
有关详细信息,请参阅$http docs中的&#34;转换请求和响应&#34;
不确定为什么要首先将其作为GET发送