Авторитарная позиция дублирования ключей HTTP GET
У меня возникли проблемы с поиском авторитетной информации о поведении с повторяющимися полями строки запроса GET HTTP, например
http://example.com/page?field=foo&field=bar
и, в частности, если порядок сохранен или нет. Большинство веб-ориентированных языков создают массив, содержащий как foo, так и bar, связанные с ключевым полем, но я хотел бы знать, существует ли авторитетное утверждение (например, в RFC) об этой точке. RFC 3986 имеет раздел 3.4. Query
, который ссылается на пары ключ = значение, но ничего не сказано о том, как интерпретировать порядок и дублировать поля и так далее на. Это имеет смысл, поскольку он зависит от бэкэнд, а не в рамках этого RFC...
Хотя существует де-факто стандарт, я бы хотел получить для него авторитетный источник, просто из любопытства.
Ответы
Ответ 1
В этом нет никакой спецификации. Вы можете делать то, что вам нравится.
Типичные подходы включают в себя: 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'
Ответ 2
Я могу подтвердить, что для 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.
Ответ 3
Большинство (все?) фреймвордов не предлагают никаких гарантий, поэтому предположим, что они будут возвращены в случайном порядке.
Всегда применяйте безопасный подход.
Например, интерфейс java HttpServlet:
ServletRequest.html#getParameterValues
Даже метод getParameterMap не содержит упоминания о порядке параметра (порядок итератора java.util.Map не может быть оговорен.)
Ответ 4
Ответ yfeldblum идеальный.
Просто примечание о пятом поведении, которое я заметил недавно: на Windows Phone, открытие приложения с помощью uri с дублирующимся ключом запроса приведет к тому, что NavigationFailed будет:
System.ArgumentException: элемент с тем же ключом уже добавлен.
Преступник System.Windows.Navigation.UriParsingHelper.InternalUriParseQueryStringToDictionary(Uri uri, Boolean decodeResults)
.
Таким образом, система даже не позволит вам обрабатывать ее так, как вы хотите, она запретит ее. Вы остаетесь единственным решением, чтобы выбрать свой собственный формат (CSV, JSON, XML,...) и uri-escape-it.
Ответ 5
Как правило, повторяющиеся значения параметров, такие как
http://example.com/page?field=foo&field=bar
приводит к одному параметру queryString, который представляет собой массив:
field[0]=='foo'
field[1]=='bar'
Я видел это поведение в ASP, ASP.NET и PHP4.
Ответ 6
У меня был тот же вопрос. Я пишу javascript функцию для синтаксического анализа и стробирования запросов. Я не знаю, имеет ли строка запроса двойные имена или имя с помощью скобок, например x [] = 1 & x [] = 2, хотя некоторые языки поддерживают этот формат.
Но я нахожу, что у Chrome и Firefox есть новый класс с именем URLSeachParams
и он поддерживает только самый простой формат как name=value
. Если в строке запроса есть повторяющиеся имена, метод get
URLSearchParams
возвращает только первый.
Так что лично, возможно, самый простой и не повторяющийся URL-адрес имен намного безопаснее для будущего.