如何使用AngularJS正确发送包含逗号的URL参数?

时间:2016-01-22 01:46:36

标签: javascript angularjs url-encoding

我有一种感觉我只是看错了,但我想通过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"

其中多个参数值是单独说明的,而不是逗号分隔?

3 个答案:

答案 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开发人员可以进行的许多调整,例如

  1. 在未转义服务器端的列表项中接受逗号的转义序列。
  2. 接受单独的网址参数中的每个项目。
  3. 通过POST接受JSON编码的正文。
  4. 您需要让API开发人员做某事

答案 1 :(得分:1)

我认为你不应该使用逗号作为数组的分隔符。

我建议

  • 使用POST发送json数据(需要更改API)

或使用其他字符串作为分隔符。例如,@@@

仅供参考,你可以简单地将你的数组加入到像这样的字符串中。

array.join(',')

答案 2 :(得分:0)

来自$ http docs

  

如果您希望仅针对单个请求覆盖请求/响应转换,则在传递到$ http的配置对象上提供transformRequest和/或transformResponse属性。

     

请注意,如果在配置对象上提供这些属性,则将覆盖默认转换。如果您希望扩充默认转换,则必须将它们包含在本地转换数组中。

简而言之,您可以使用encodeURIComponent()功能通过在每个请求的配置对象中包含transformRequest属性来替换默认值,或者您可以建立全局覆盖

有关详细信息,请参阅$http docs中的&#34;转换请求和响应&#34;

不确定为什么要首先将其作为GET发送