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

发布于 2024-08-11 14:01:49 字数 443 浏览 2 评论 0原文

我在查找有关 HTTP GET 查询字符串重复字段行为的权威信息时遇到了麻烦,例如,

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

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

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

I am having trouble on finding authoritative information about the behavior with HTTP GET query string duplicate fields, like

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

and in particular if the order is kept or not. Most web-oriented languages produce an array containing both foo and bar associated to a key "field", but I would like to know if authoritative statement exist (e.g. on a RFC) about this point. RFC 3986 has a section 3.4. Query, which refers to key=value pairs, but nothing is said on how to interpret order and duplicate fields and so on. This makes sense, since it's backend dependent, and not in the scope of that RFC...

Although a de-facto standard exists, I'd like to see an authoritative source for it, just out of curiosity.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

香橙ぽ 2024-08-18 14:01:50

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

The situation seems to have changed since this question was asked and the accepted answer was written 12 years ago. I believe we now have an authoritative source: The WHATWG URL Standard describes the process of extracting and parsing a query string in detail in section 6.2 (https://url.spec.whatwg.org/#interface-urlsearchparams) and section 5.1 on x-www-form-urlencoded parsing (https://url.spec.whatwg.org/#urlencoded-parsing). The parsing output is "an initially empty list of name-value tuples where both name and value hold a string", where a list is defined as a finite ordered sequence, and the key-value pairs are added to this list in the order they appear in the URL. At first there is no mention of repeated keys, but some methods on the URLSearchParams class in section 6.2 (https://url.spec.whatwg.org/#interface-urlsearchparams) set clear expectations on ordering: "The getAll(name) method steps are to return the values of all name-value pairs whose name is name... in list order"; The sort() method specifies that "The relative order between name-value pairs with equal names must be preserved." (Emphasis mine). Examining the Github issue referenced in the commit where the sort method was added, we see that the original proposal was to sort on values where keys were identical, but this was changed: "The reason for the default sort not affecting the value order is that ordering of the values can be significant. We should not assume that it's ok to move the order of the values around." (https://github.com/whatwg/url/issues/26#issuecomment-271600764)

零度℉ 2024-08-18 14:01:50

我可以确认,对于 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 数据是相同的。

I can confirm that for PHP (at least in version 4.4.4 and newer) it works like this:

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

results in:

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

But

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

results in:

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

This behavior is the same for GET and POST data.

寂寞清仓 2024-08-18 14:01:50

yfeldblum 的答案是完美的。

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

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

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

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

yfeldblum's answer is perfect.

Just a note about a fifth behavior I noticed recently: on Windows Phone, opening an application with an uri with a duplicate query key will result in NavigationFailed with:

System.ArgumentException: An item with the same key had already been added.

The culprit is System.Windows.Navigation.UriParsingHelper.InternalUriParseQueryStringToDictionary(Uri uri, Boolean decodeResults).

So the system won't even let you handle it the way you want, it will forbid it. You are left with the only solution to choose your own format (CSV, JSON, XML, ...) and uri-escape-it.

赠我空喜 2024-08-18 14:01:50

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

始终采取最安全的方法。

例如java HttpServlet接口:
ServletRequest。 html#getParameterValues

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

Most (all?) of the frameworks offer no guarantees, so assume they will be returned in random order.

Always take the safest approach.

For example, java HttpServlet interface:
ServletRequest.html#getParameterValues

Even the getParameterMap method leaves out any mention about parameter order (the order of a java.util.Map iterator cannot be relied on either.)

情泪▽动烟 2024-08-18 14:01:50

通常,重复的参数值会

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

产生一个数组形式的 queryString 参数:

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

我在 ASP、ASP.NET 和 PHP4 中见过这种行为。

Typically, duplicate parameter values like

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

result in a single queryString parameter that is an array:

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

I've seen this behavior in ASP, ASP.NET and PHP4.

一场信仰旅途 2024-08-18 14:01:50

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

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

The ?array[]=value1&array[]=value2 approach is certainly a very popular one.

  • supported by most Javascript frameworks
  • supported by Java Spring
  • supported by PHP
月光色 2024-08-18 14:01:49

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

典型的方法包括:第一个给定的、最后给定的、全部数组、全部字符串连接和逗号。

假设原始请求是:

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'

There is no spec on this. You may do what you like.

Typical approaches include: first-given, last-given, array-of-all, string-join-with-comma-of-all.

Suppose the raw request is:

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

Then there are various options for what request.query['tag'] should yield, depending on the language or the framework:

request.query['tag'] => 'ruby'
request.query['tag'] => 'rails'
request.query['tag'] => ['ruby', 'rails']
request.query['tag'] => 'ruby,rails'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文