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

时间:2021-09-24 19:42:17

I have a feeling I am just looking at this wrong, but I want to get feedback on the proper way to pass URL query parameters through Angular's $http.get() method - specifically, parameters that contain commas.

我有一种感觉,我只是看错了这个地方,但是我想要得到关于通过角的$http.get()方法传递URL查询参数的正确方法的反馈——特别是包含逗号的参数。

Let's say I have the following data, to be used as URL parameters in a GET request:

假设我有以下数据,作为GET请求中的URL参数:

var params = {
  filter : [
     "My filter",
     "My other filter",
     "A filter, that contains, some commas"
  ],
  sort : [
     "ascending"
  ]
};

Now, I convert this structure to some parameters that can be fed into $http.get:

现在,我将这个结构转换为一些参数,这些参数可以输入$http。

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] += ","
       }
    }
}

At this point, urlParams looks like this:

此时,urlParams是这样的:

{
  filter : "My filter,My other filter,A filter, that contains, some commas",
  sort : "ascending"
}

Now, that isn't what I want, since the third filter parameter has now turned into three separate parameters. (The API I am working with does not allow multiple values for a parameter to be passed in any other way than: "?param=value1,value2,value3") So, what I need to do is URI encode these values first, right? So, I add a encodeURIComponent() to the above routine like this:

这不是我想要的,因为第三个过滤器参数现在已经变成了三个独立的参数。(我使用的API不允许以任何其他方式传递参数的多个值:“?param=value1,value2,value3”)因此,我需要做的是首先对这些值进行URI编码,对吗?因此,我在上面的例程中添加了一个encodeURIComponent():

urlParams[name] += encodeURIComponent(value[i]);

This gives me a parameters object that looks like this:

这给了我一个这样的参数对象:

{
  filter : "My%20filter,My%20other%20filter,A%20filter%2C%20that%20contains%2C%20some%20commas",
  sort : "ascending"
}

Now, I make a request:

现在,我请求:

var config = {
  params : urlParams
};
$http.get("/foo", config).then(function(response){
  console.log(response);
});

... and this doesn't work, since Angular encodes the URL parameters as well, so the request ends up looking like this:

…这是行不通的,因为角编码了URL参数,所以请求最终会是这样的:

GET "/foo?filter=My%2520filter,My%2520other%2520filter,A%2520filter%2C%20that%20contains%2C%20some%20commas&sort=ascending"

As you can see the parameters are being encoded twice (the % signs are being encoded as %25), which of course, won't work.

正如您所看到的,参数被编码了两次(%符号被编码为%25),当然,这是行不通的。

Obviously, I am doing it wrong. But what is the right way? Or, do I need to ask the API developer to accept URL parameters like this?

显然,我做错了。但是正确的方法是什么呢?或者,我是否需要要求API开发人员接受这样的URL参数?

GET "/foo?filter=My+filter,+with+a+comma&filter=Another+filter"

where multiple parameter values are stated separately, instead of being comma delimited?

当多个参数值分别声明时,而不是用逗号分隔?

3 个解决方案

#1


5  

As you've described the API, there is no way to reliably pass values containing commas.

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

Suppose you want to pass the items ["one","two","three,four"] as a list.

假设您想要将项(“1”、“2”、“3”、“4”)作为一个列表进行传递。

  • If you pass the strings as-is, the API will see (after the normal server-side URL decoding)

    如果您按原样传递字符串,API将会看到(在正常的服务器端URL解码之后)

    one,two,three,four
    

    which makes the three,four indistinguishable from two separate items.

    这使得这三种,四种区别于两种不同的东西。

  • If you pass the strings URL-encoded, the entire parameter will be double-encoded, and the API will see (again, after URL decoding)

    如果您传递字符串URL编码,则整个参数将被双编码,API将会看到(同样,在URL解码之后)

    one,two,three%2Cfour
    

    Now the parameters are distinguishable, but this requires support from the API to URL-decode each item separately.

    现在参数是可以区分的,但是这需要来自API的支持来分别对每个项目进行url解码。

  • Suppose you pass the strings like one,two,"three,four", i.e. items containing commas are quoted. The API can decode the parameters correctly, but it needs to support a more complex syntax (quoted strings) instead of simply splitting by commas...

    假设您传递字符串,比如1、2、“3、4”,即包含引号的项。API可以正确地解码参数,但是它需要支持更复杂的语法(引用的字符串),而不是简单地用逗号分隔。

...and so on. The bottom line is that without additional support from the API, I don't think there is anything you can do client-side to trick it into decoding strings containing commas correctly. There are many tweaks that the API developer can make, e.g.

…等等。最重要的是,如果没有API的额外支持,我认为客户端不可能做任何事情来欺骗它去正确地解码包含逗号的字符串。API开发人员可以做很多调整。

  1. Accepting some escape sequence for commas within list items which is unescaped server-side.
  2. 在未转义服务器端列表项中接受逗号的转义序列。
  3. Accepting each item in a separate URL parameter.
  4. 在单独的URL参数中接受每个项。
  5. Accepting JSON-encoded body via POST.
  6. 通过POST接受json编码的主体。

You will need to ask the API developer to do something.

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

#2


1  

I think you shouldn't have used comma as delimiter of the array.

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

I would recommend to

我建议

  • send json data using POST (which requires API change)
  • 使用POST发送json数据(需要修改API)

or use another string as delimiter. For example, @@@.

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

FYI, you can simply join your array into string like this.

简单地说,你可以像这样把数组加入到字符串中。

array.join(',')

array.join(" ")

#3


0  

From $http docs

从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.

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

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.

注意,如果在config对象上提供这些属性,那么默认的转换将被覆盖。如果希望增加默认转换,则必须将它们包含在本地转换数组中。

In short you can use your encodeURIComponent() functionality to replace the default one by including transformRequest property in the config object for each request or you can establish a global override

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

See "Transforming Requests and Responses" in $http docs for more details

有关更多细节,请参阅$http文档中的“转换请求和响应”

Not sure why you want to send this as GET in the first place

不确定为什么要发送这个作为GET的第一步

#1


5  

As you've described the API, there is no way to reliably pass values containing commas.

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

Suppose you want to pass the items ["one","two","three,four"] as a list.

假设您想要将项(“1”、“2”、“3”、“4”)作为一个列表进行传递。

  • If you pass the strings as-is, the API will see (after the normal server-side URL decoding)

    如果您按原样传递字符串,API将会看到(在正常的服务器端URL解码之后)

    one,two,three,four
    

    which makes the three,four indistinguishable from two separate items.

    这使得这三种,四种区别于两种不同的东西。

  • If you pass the strings URL-encoded, the entire parameter will be double-encoded, and the API will see (again, after URL decoding)

    如果您传递字符串URL编码,则整个参数将被双编码,API将会看到(同样,在URL解码之后)

    one,two,three%2Cfour
    

    Now the parameters are distinguishable, but this requires support from the API to URL-decode each item separately.

    现在参数是可以区分的,但是这需要来自API的支持来分别对每个项目进行url解码。

  • Suppose you pass the strings like one,two,"three,four", i.e. items containing commas are quoted. The API can decode the parameters correctly, but it needs to support a more complex syntax (quoted strings) instead of simply splitting by commas...

    假设您传递字符串,比如1、2、“3、4”,即包含引号的项。API可以正确地解码参数,但是它需要支持更复杂的语法(引用的字符串),而不是简单地用逗号分隔。

...and so on. The bottom line is that without additional support from the API, I don't think there is anything you can do client-side to trick it into decoding strings containing commas correctly. There are many tweaks that the API developer can make, e.g.

…等等。最重要的是,如果没有API的额外支持,我认为客户端不可能做任何事情来欺骗它去正确地解码包含逗号的字符串。API开发人员可以做很多调整。

  1. Accepting some escape sequence for commas within list items which is unescaped server-side.
  2. 在未转义服务器端列表项中接受逗号的转义序列。
  3. Accepting each item in a separate URL parameter.
  4. 在单独的URL参数中接受每个项。
  5. Accepting JSON-encoded body via POST.
  6. 通过POST接受json编码的主体。

You will need to ask the API developer to do something.

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

#2


1  

I think you shouldn't have used comma as delimiter of the array.

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

I would recommend to

我建议

  • send json data using POST (which requires API change)
  • 使用POST发送json数据(需要修改API)

or use another string as delimiter. For example, @@@.

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

FYI, you can simply join your array into string like this.

简单地说,你可以像这样把数组加入到字符串中。

array.join(',')

array.join(" ")

#3


0  

From $http docs

从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.

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

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.

注意,如果在config对象上提供这些属性,那么默认的转换将被覆盖。如果希望增加默认转换,则必须将它们包含在本地转换数组中。

In short you can use your encodeURIComponent() functionality to replace the default one by including transformRequest property in the config object for each request or you can establish a global override

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

See "Transforming Requests and Responses" in $http docs for more details

有关更多细节,请参阅$http文档中的“转换请求和响应”

Not sure why you want to send this as GET in the first place

不确定为什么要发送这个作为GET的第一步