Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authoritative position of duplicate HTTP GET query keys

Tags:

http

uri

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'

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.


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.


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