Authoritative position of duplicate HTTP GET query

2019-01-01 09:06发布

问题:

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.

回答1:

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\'


回答2:

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.



回答3:

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.



回答4:

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



回答5:

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.



回答6:

I had the same question. I am writing javascript function to parse and stringify queries. I don\'t know if a query string has duplicate names or name with brackets, such as x[]=1&x[]=2, is standard though some language support these format.

But I find that Chrome and Firefox has an new Class named URLSeachParams and It only support the simplest format as name=value. If there are duplicate names in query string, the get method of URLSearchParams only return the first one.

So personally, maybe an simplest and no duplicate names url is much more safer for future.



标签: http uri