Официальная позиция дублированных ключей запроса 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-адрес гораздо безопаснее в будущем.

Другие вопросы по тегам