Почему кодировка URL-адреса и части строки запроса различаются?

Я исследовал, почему в параметрах моего запроса есть знак плюс + вместо %20 и почему они имеют такие строки, как %C3%BC вместо ü (UTF-8), как в закодированном URL-адресе.

После 2 часов размышлений мое веб-приложение несовместимо со стандартом кодирования URL-адресов, и я обнаружил, что схема кодирования строки запроса не совпадает с кодировкой URL-адреса (здесь я имею в виду часть без строки запроса).

Примеры:

  • URL:
    • whitespace encodes to %20
    • Символы UTF-8 остаются символами UTF-8
  • Query params:
    • whitespace encodes to +
    • Символы UTF-8 кодируются в шестнадцатеричное представление

Так может ли кто-нибудь сказать мне, почему схемы кодирования различаются, поскольку параметры запроса являются частью URL-адреса?

Видеть:


person moritz    schedule 20.03.2011    source источник


Ответы (3)


URI возникли в RFC 1630, где процентное кодирование используется как метод, разрешающий "небезопасные "представляемые символы. В этой исходной версии фактически упоминался набор символов ISO Latin 1 как кодировка для символов, отличных от ASCII. RFC 1738 позже в том же году удалил эту ссылку на Latin-1 в определении URL-адресов.

Формат строки запроса на самом деле является другой, но родственной кодировкой, application/x-www-form-urlencoded, определенной в RFC 1866 вместе с HTML 2.0. Он был основан на RFC 1738, но указывал, что пробелы (не все пробелы, а только символ с кодом ASCII 0x20) заменяется на «+», а разрывы строк должны кодироваться как CRLF (т. е. %0D%0A). Первое, вероятно, связано с тем, что это экономит 2 байта для очень распространенного символа при отправке формы за счет использования дополнительных 2 байтов для гораздо менее распространенного символа, а второе — для того, чтобы избежать проблем при передаче между системами, использующими разные окончания. линейные кодировки. Символы, отличные от ASCII, не учитывались.

Кодирование UTF-8 в URI появилось более десяти лет спустя, в RFC 3986, хотя отдельные протоколы могли указать эту или другую кодировку символов, отличных от ASCII, ранее. Для обеспечения обратной совместимости все октеты UTF-8 должны быть закодированы в процентах. Сопутствующий RFC 3987 определяет "интернационализированные идентификаторы ресурсов" (IRI), которые в основном " URI с большинством кодовых точек 160 и выше могут отображаться незакодированными», но многие протоколы по-прежнему требуют URI. Обратите внимание, что ваше утверждение выше неверно, так как URL не может содержать незакодированный символ ü или любой другой символ, отличный от ASCII.

application/x-www-form-urlencoded был интернационализирован другим способом. HTML5-спецификация application/x-www-form-urlencoded явно разрешает использование любого ASCII-совместимого набора символов для символов в строке запроса и фактически для разных полей могут использовать разные наборы символов, но все октеты, отличные от ASCII, все равно должны быть закодированы в процентах. При использовании в части запроса IRI возможно, что эти символы могут быть представлены незакодированными, если в качестве набора символов используется должным образом нормализованная кодировка UTF-8, так как преобразование обратно в URI приведет к в правильных данных application/x-www-form-urlencoded.

person Anomie    schedule 25.03.2011

Они не обязательно должны должны различаться, + — это допустимый символ пути, а ü — допустимый символ поиска (в соответствии с RFC 3987). Вы, вероятно, видите, что браузеры или какая-то другая предвзятая схема кодирования делает предположения, которые либо устарели, либо слишком осторожны.

person eyelidlessness    schedule 20.03.2011
comment
+1 за то, что указал мне на RFC 3987, но я подожду, может быть, кто-нибудь скажет мне, почему это различие было в первую очередь. Также теперь возникает вопрос, почему все основные кодировщики параметров запроса Java не интернационализированы, но это другой вопрос :). - person moritz; 20.03.2011

Нет никакой разницы между + и %20, когда речь идет о параметрах строки запроса:

ПРОБЕЛ кодируется как «+» или «% 20»

Цитата

person Darush    schedule 24.06.2017
comment
Это относится только к параметрам формы в строках запроса. - person Julian Reschke; 25.06.2017