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

How to properly send URL parameters containing commas using AngularJS?

我觉得我只是看错了,但我想获得有关通过 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"

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

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

我会推荐给

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

或使用另一个字符串作为分隔符。例如,@@@.

仅供参考,您可以像这样简单地将数组连接到字符串中。

array.join(',')

来自 $http 文档

If you wish override the request/response transformations only for a single request then provide transformRequest and/or transformResponse properties on the configuration object passed into $http.

Note that if you provide these properties on the config object the default transformations will be overwritten. If you wish to augment the default transformations then you must include them in your local transformation array.

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

有关详细信息,请参阅 $http docs 中的 “转换请求和响应”

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

如您所述API,无法可靠地传递包含逗号的值。

假设您要将项目 ["one","two","three,four"] 作为列表传递。

  • 如果传递字符串as-is,API会看到(正常server-sideURL解码后)

    one,two,three,four
    

    这使得 three,four 与两个单独的项目无法区分。

  • 如果传递字符串 URL-encoded,整个参数将为 double-encoded,API 将看到(同样,在 URL 之后解码)

    one,two,three%2Cfour
    

    现在参数可区分的,但这需要API到URL-decode每一项分别支持。

  • 假设您传递像 one,two,"three,four" 这样的字符串,即包含逗号的项目被引用。 API 可以 正确解码参数,但它需要支持更复杂的语法(带引号的字符串)而不是简单地用逗号分隔...

...等等。底线是,如果没有 API 的额外支持,我认为您无法 client-side 欺骗它正确解码包含逗号的字符串。 API 开发人员可以进行许多调整,例如

  1. 在未转义的列表项中接受逗号的一些转义序列 server-side。
  2. 在单独的 URL 参数中接受每个项目。
  3. 通过 POST 接受 JSON-encoded 正文。

您需要让 API 开发人员做一些事情