Официальная позиция дублированных ключей запроса HTTP GET
У меня проблемы с поиском достоверной информации о поведении с помощью повторяющихся полей строки запроса HTTP GET, например
http://example.com/page?field=foo&field=bar
и в частности, если заказ сохранен или нет. Большинство веб-ориентированных языков создают массив, содержащий как foo, так и bar, связанные с ключевым "полем", но я хотел бы знать, существует ли авторитетное утверждение (например, в RFC) по этому вопросу. RFC 3986 имеет раздел 3.4. Query
, что относится к парам ключ = значение, но ничего не сказано о том, как интерпретировать порядок и дублировать поля и так далее. Это имеет смысл, так как это зависит от бэкэнда, а не в рамках этого RFC...
Хотя стандарт де-факто существует, я бы хотел увидеть для него авторитетный источник, просто из любопытства.
8 ответов
Там нет никаких спецификаций по этому вопросу. Вы можете делать то, что вам нравится.
Типичные подходы включают в себя: первый дан, последний дан, массив всех, строка-соединение-с-запятой-всех.
Предположим, что необработанный запрос:
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'
Ситуация, похоже, изменилась с тех пор, как этот вопрос был задан, а принятый ответ был написан 12 лет назад. Я считаю, что теперь у нас есть авторитетный источник: стандарт URL-адресов WHATWG подробно описывает процесс извлечения и анализа строки запроса в разделе 6.2 () и разделе 5.1 на парсинг x-www-form-urlencoded (https://url.spec.whatwg.org/#urlencoded-parsing). Результат синтаксического анализа представляет собой «изначально пустой список кортежей «имя-значение», где и имя, и значение содержат строку», где список определяется как конечный упорядоченный список.последовательность, и пары ключ-значение добавляются в этот список в том порядке, в котором они появляются в URL-адресе. Сначала не упоминаются повторяющиеся ключи, но некоторые методы класса URLSearchParams в разделе 6.2 (https://url.spec.whatwg.org/#interface-urlsearchparamshttps://url.spec.whatwg.org/#interface-urlsearchparams) задают четкие требования к упорядочению:
getAll(name)
шаги метода должны вернуть значения всех пар имя-значение, чье имя имеет имя... в порядке списка ";
sort()
Метод указывает, что « Относительный порядок между парами имя-значение с одинаковыми именами должен быть сохранен ». (Выделено мое). Изучая проблему Github, упомянутую в коммите, где был добавлен метод сортировки, мы видим, что исходное предложение заключалось в сортировке по значениям, где ключи были идентичны, но это было изменено: «Причина сортировки по умолчанию, не влияющая на порядок значений, заключается в том, что порядок значений может быть значительным . Мы не должны предполагать, что можно изменить порядок значений». (https://github.com/whatwg/url/issues/26#issuecomment-271600764)
Я могу подтвердить, что для 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 идеален.
Просто заметка о пятом поведении, которое я недавно заметил: на Windows Phone открытие приложения с URI с дублирующим ключом запроса приведет к NavigationFailed с:
System.ArgumentException: элемент с тем же ключом уже был добавлен.
Виновником является System.Windows.Navigation.UriParsingHelper.InternalUriParseQueryStringToDictionary(Uri uri, Boolean decodeResults)
,
Таким образом, система даже не позволит вам справиться с этим так, как вы хотите, она запретит это. У вас остается единственное решение - выбрать свой собственный формат (CSV, JSON, XML, ...) и uri-escape-it.
Большинство (все?) Платформ не дают никаких гарантий, поэтому предположим, что они будут возвращены в случайном порядке.
Всегда используйте самый безопасный подход.
Например, интерфейс Java HttpServlet: ServletRequest.html # getParameterValues
Даже метод getParameterMap не учитывает никакого порядка порядка параметров (на порядок итератора java.util.Map также нельзя полагаться).
Как правило, повторяющиеся значения параметров, такие как
http://example.com/page?field=foo&field=bar
результат в единственном параметре queryString, который является массивом:
field[0]=='foo'
field[1]=='bar'
Я видел это поведение в ASP, ASP.NET и PHP4.
The
?array[]=value1&array[]=value2
подход, безусловно, очень популярен.
- поддерживается большинством фреймворков Javascript
- поддерживается Java Spring
- поддерживается PHP
У меня такой же вопрос. Я пишу функцию JavaScript для анализа и строковых запросов. Я не знаю, является ли стандартная строка запроса дублирующимися именами или именами в скобках, например, x[]=1&x[]=2, хотя некоторые языки поддерживают этот формат.
Но я считаю, что Chrome и Firefox имеют новый класс под названием URLSeachParams
и он поддерживает только самый простой формат name=value
, Если в строке запроса есть повторяющиеся имена, get
метод URLSearchParams
верните только первый.
Так что лично, возможно, самый простой и не повторяющийся URL-адрес гораздо безопаснее в будущем.