重复HTTP GET查询键的权威位置

时间:2009-11-17 04:04:37

标签: http uri

我无法通过HTTP GET查询字符串重复字段查找有关行为的权威信息,例如

http://example.com/page?field=foo&field=bar 

,特别是如果保留订单。大多数面向Web的语言产生一个包含与关键“字段”相关联的foo和bar的数组,但我想知道是否存在关于这一点的权威声明(例如在RFC上)。 RFC 3986有一个3.4. Query部分,它引用了键=值对,但没有说明如何解释顺序和重复字段等等。这是有道理的,因为它依赖于后端,而不在RFC的范围内......

虽然存在事实上的标准,但我希望看到它的权威来源,只是出于好奇。

7 个答案:

答案 0 :(得分:102)

上没有规范。你可以做你喜欢的事。

典型方法包括:first-given,last-given,array-of-all,string-join-with-comma-of-all。

假设原始请求是:

GET /blog/posts?tag=ruby&tag=rails HTTP/1.1
Host: example.com

然后根据语言或框架,request.query['tag']应该有多种选择:

request.query['tag'] => 'ruby'
request.query['tag'] => 'rails'
request.query['tag'] => ['ruby', 'rails']
request.query['tag'] => 'ruby,rails'

答案 1 :(得分:14)

我可以确认对于PHP(至少在4.4.4及更高版本中),它的工作原理如下:

GET /blog/posts?tag=ruby&tag=rails HTTP/1.1
Host: example.com

结果:

request.query['tag'] => 'rails'

但是

GET /blog/posts?tag[]=ruby&tag[]=rails HTTP/1.1
Host: example.com

结果:

request.query['tag'] => ['ruby', 'rails']

GET和POST数据的行为相同。

答案 2 :(得分:7)

yfeldblum的答案是完美的。

关于我最近注意到的第五种行为的注释:在 Windows Phone 上,使用带有重复查询键的uri打开应用程序将导致NavigationFailed:

  

System.ArgumentException:已添加具有相同键的项目。

罪魁祸首是System.Windows.Navigation.UriParsingHelper.InternalUriParseQueryStringToDictionary(Uri uri, Boolean decodeResults)

所以系统甚至不会让你按照你想要的方式处理它,它会禁止它。您将拥有选择自己的格式(CSV,JSON,XML,...)和uri-escape-it的唯一解决方案。

答案 3 :(得分:5)

大多数(全部?)框架都不提供任何保证,因此假设它们将以随机顺序返回。

始终采取最安全的方法。

例如,java HttpServlet接口: ServletRequest.html#getParameterValues

即使 getParameterMap 方法也没有提及有关参数顺序的任何提及(也不能依赖java.util.Map迭代器的顺序。)

答案 4 :(得分:4)

通常,重复参数值,如

http://example.com/page?field=foo&field=bar

产生一个queryString参数,它是一个数组:

field[0]=='foo'
field[1]=='bar'

我在ASP,ASP.NET和PHP4中看到过这种行为。

答案 5 :(得分:0)

我有同样的问题。我正在编写javascript函数来解析和字符串化查询。我不知道查询字符串是否有重复的名称或带括号的名称,例如x [] = 1& x [] = 2,虽然某些语言支持这些格式,但它是标准的。

但我发现Chrome和Firefox有一个名为URLSeachParams的新类,它只支持最简单的格式name=value。如果查询字符串中存在重复的名称,则get URLSearchParams方法仅返回第一个。

所以个人而言,也许最简单,没有重复名称的网址对未来来说更安全。

答案 6 :(得分:0)

?array[]=value1&array[]=value2 方法当然是一种非常流行的方法。

  • 大多数 Javascript 框架都支持
  • 由 Java Spring 支持
  • 由 PHP 支持