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

我在查找有关 HTTPGET 查询字符串重复字段的行为的权威信息方面遇到了麻烦,比如

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

特别是如果命令是否得到遵守。大多数面向 Web 的语言都会生成一个数组,其中包含与关键字“ field”关联的 foo 和 bar,但是我想知道是否存在关于这一点的权威性陈述(例如在 RFC 上)。RFC 3986有一个 3.4. Query部分,它引用键 = 值对,但是没有说明如何解释顺序和重复字段等等。这是有意义的,因为它是依赖于后端的,而不在 RFC 的范围内..。

虽然存在一个事实上的标准,但出于好奇,我希望看到一个权威的源代码。

48710 次浏览

通常,重复的参数值如

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

结果为一个数组形式的 queryString 参数:

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

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

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

总是采取最安全的方法。

例如,java HttpServlet 接口: 获取参数值

甚至 获取参数地图方法也没有提到参数顺序(java.util 的顺序)。映射迭代器也不可靠。)

这上面有 没有规格。你可以做你想做的。

典型的方法包括: first-give、 last-give、 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'

我可以确认,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 数据的这种行为是相同的。

Yfeldblum 的回答是完美的。

我最近注意到的第五个行为: 在 微软手机上,用带有重复查询键的 uri 打开一个应用程序,将导致 NavigationFail:

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

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

所以系统甚至不会让你按照你想要的方式来处理它,它会禁止你这么做。剩下的唯一解决方案是选择自己的格式(CSV、 JSON、 XML、 ...)和 uri-escape-it。

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

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

自从12年前提出这个问题并写出公认的答案以来,情况似乎发生了变化。我相信我们现在有了一个权威的来源: WHATWG URL 标准在6.2节(https://url.spec.whatwg.org/#interface-urlsearchparams)和5.1节(x-www-form-urlencode parsing (https://url.spec.whatwg.org/#urlencoded-parsing))中详细描述了提取和解析查询字符串的过程。解析输出是“一个名称-值元组的初始空列表,其中名称和值都包含一个字符串”,其中一个列表被定义为一个有限的 命令序列,键-值对按照它们在 URL 中出现的顺序添加到这个列表中。一开始没有提到重复键,但是6.2节(https://url.spec.whatwg.org/#interface-urlsearchparams)中 URLSearchParams 类的一些方法对排序设置了明确的期望: “ getAll(name)方法的步骤是返回所有名称为... 按顺序排列的名称-值对的值; sort()方法指定了“ 必须保留具有相同名称的名称-值对之间的相对顺序。”(强调我的)。通过检查添加了排序方法的提交中引用的 Github 问题,我们发现最初的提议是对键相同的值进行排序,但是这个提议改变了: “默认排序不影响值顺序的原因是 值的顺序可能很重要。我们不应该认为可以随意改变价值观的顺序。”(https://github.com/whatwg/url/issues/26#issuecomment-271600764)