Русский

Инструменты разработчика · Кодер и декодер URL

От RFC 1738 к стандарту URL: как развивались правила процентного кодирования

· Фон

URL-кодировка RFC-история веб-стандарты

Эволюция стандартов процентного кодирования URL от RFC 1738 через RFC 3986 до стандарта WHATWG URL
Оригинальная векторная иллюстрация ToolAcre

Правила экранирования символов в URL-адресах переписывались несколько раз, начиная с 1994. Этот пост соответствует стандарту RFC 1738, RFC 2396, RFC 3986 и стандарту WHATWG URL и объясняет, что изменилось каждый раз.

От RFC 1738 до стандарта URL — как развивались правила процентного кодирования

Тильда (~) показывает, как правила кодирования меняются в зависимости от поколения и внедрения стандартов. RFC 1738 (1994) везде требуется %7E; RFC 2396 (1998) перенес тильду в незарезервированное положение, что позволяет использовать незакодированное значение. RFC 3986 (2005) подтвердил незарезервированный статус. Старые URL-адреса с %7E остаются действительными; выход новых строителей ~. Эволюция отражает уроки развертывания по мере развития Интернета и стандартизации инфраструктуры. RFC 1738 был консервативным, поскольку ранняя инфраструктура была неоднородной и разнообразной.

RFC 1738 кодифицировал поведение браузера 1994. Развертывания стандартизированы на UTF-8; ограничения оказались излишними. Более поздние стандарты ослабили ограничения на характеры. RFC 3986 разрешает безопасное декодирование незарезервированных символов.

RFC 1738 (1994): «небезопасные» символы и первые правила экранирования — что считалось опасным и почему

RFC 1738 определил «небезопасные» символы как те, которые конфликтуют с синтаксисом URI (пробел, косая черта), исторически использовались в протоколах (управляющие символы) или которые системы не могут безопасно передавать. Консервативный список закодирован в процентах гораздо больше, чем необходимо современному Интернету. Многие ранние системы предшествовали RFC; это кодифицировало их поведение. Управляющие персонажи были действительно опасны в протоколах; пробелы были проблемами передачи для клиентов HTTP, читающих из командной строки. Современные системы более изящно справляются с этими случаями посредством явного кодирования.

Тестирование против RFC 1738 показывает, чего ожидали старые системы. Закодируйте символ из спецификации URL 1990-х годов и сравните его с современным RFC 3986. Различия показывают, что расслабились. Незарезервированный набор со временем расширялся. Дефис, точка и подчеркивание всегда безопасны. Тильде понадобилось RFC 2396, чтобы оказаться в безопасности. Консервативный подход подразумевал обратную совместимость. Старые URL-адреса, созданные в соответствии с правилами RFC 1738, остаются действительными и сегодня. Нормализация в разделе RFC 3986 6 позволяет безопасно декодировать незарезервированные символы с ненужной процентной кодировкой.

RFC 2396 (1998) — зарезервировано или незарезервировано, общий синтаксис и восстановлена ​​тильда

RFC 2396 (1998) уточняет наборы символов более строго, чем RFC 1738. Он формализовал зарезервированные символы, служащие структуре URI, а не незарезервированные как литеральные данные. Незарезервированное расширение, включая дефис, точку, подчеркивание и тильду. Он признал общий синтаксис URI отдельно от правил, специфичных для схемы. RFC 2396 ввел различие между ген-разделителями (:, /, ?, #, [, ], @) и подразделителями (!, $, &, ', (, ), *, +, ,, ;, =). Именование проясняет разделение зарезервированных символов на две группы с разными структурными ролями.

RFC 2396 представило руководство по нормализации, определяющее, какие символы с процентной кодировкой можно декодировать без каких-либо изменений. Декодирование незарезервированных символов нормализуется. Зарезервированные кодировки символов. RFC 3986 еще больше упростил обозначения. Стандарты яростно поддерживают обратную совместимость.

RFC 3986 (2005) — ! * ' ( ) переход к суб-разделителям, ген-разделителям присваиваются имена и появляются рекомендации по нормализации

RFC 3986 (2005) — современный эталонный стандарт процентного кодирования. Он сохранил зарезервированное различие/unreserved, но упростил обозначения и добавил рекомендации по нормализации. Тильда двигалась однозначно и непринужденно. Стандартные незарезервированные символы с уточненной процентной кодировкой можно декодировать без каких-либо изменений. RFC 3986 раздел 3 точно описывает синтаксис URI. Раздел 2 определяет категории символов. Раздел 6 посвящен формальным правилам синтаксической нормализации. Нормализация на основе сравнения считает URI идентичными, если нормализованные формы совпадают. Удаление точечных сегментов из путей нормализует без каких-либо изменений.

Нормализация важна для аналитики, кэширования, перехода по ссылкам. URL-адреса, отличающиеся только шестнадцатеричным регистром цифр (RFC 3986 предпочитает верхний регистр), на практике должны быть идентичными. Нормализация предотвращает дублирование записей журнала и промахи в кэше. Кэши, привязанные к нормализованным URL-адресам, обслуживают контент независимо от предпочтений кодировки запрашивающей стороны. RFC 3986 руководство по нормализации позволяет системам принимать согласованные решения. Но строгое соблюдение требований нарушает нормальное функционирование URL-адресов в современном Интернете.

Стандарт WHATWG URL: анализ того, что на самом деле получают браузеры — наборы кодировок, специальные схемы и устойчивость к ошибкам

WHATWG URL Стандарт (2016 – присутствует) возник в результате использования браузера с URL-адресами, которые не полностью соответствуют RFC 3986. Браузеры сталкивались с незакодированными пробелами, смешанными кодировками, особенностями. WHATWG описывает реальный анализ браузера, а не теоретическую грамматику. Реальные браузеры разработали практические правила для допуска пробелов, обработки экранированных символов и восстановления после неправильного ввода. RFC 3986 появился в 2005 и определил формальную грамматику, но на практике браузеры уже немного разошлись.

WHATWG определяет девять наборов кодирования с контекстно-зависимыми правилами. Пробел в пути становится %20; косая черта в информации о пользователе становится %2F. Браузер применяет более узкий стандарт для Интернета. RFC 3986 обеспечивает базовый уровень; WHATWG основан на этом.

Рабочий пример: один URL с тильдой, пробелом и символом, отличным от ASCII — как его кодирует каждое поколение правил.

Интернационализированные домены используют кодировку Punycode (München становится xn--mnchen-3ya). Пути и запросы по-прежнему используют процентное кодирование. Доменная часть использует punycode; В частях пути и запроса используется процентное кодирование. Слои не перемешиваются и не мешаются.

IDNA (Интернационализированные доменные имена в приложениях) решает проблему с именем хоста. Punycode кодирует не-ASCII в ASCII для совместимости с DNS. Префикс xn-- сигнализирует о кодировке Punycode. Алгоритм детерминирован: münchen всегда становится xn--mnchen-3ya. Символы, отличные от ASCII, должны быть преобразованы до разрешения DNS. Процентное кодирование не работает для имен хостов из-за ограничений DNS и ограничений меток. Каждый подход правильно решает разные проблемы. Стандарты развивались отдельно по веским причинам.

Чего это не касается — IRI и интернационализированные доменные имена, имеющие свою историю.

Выбор стандартов зависит от контекста. Создаете URL-адреса для браузеров? Следуйте RFC 3986; браузеры применяют WHATWG. Старые системы? Тестовые реализации. Понимание эволюции предотвращает путаницу.

Современные строители должны следовать RFC 3986 или WHATWG контекстуально. Старые и новые URL-адреса сосуществуют, что требует тщательного продумывания совместимости. Кодер и декодер URL следует за RFC 3986 повсюду, предлагая фиксированную ссылку, отдельную от поведения браузера. WHATWG добавляет наборы кодировок для конкретных компонентов помимо базовых возможностей RFC. Знание того, что когда-то изменилось, помогает понять, почему системы расходятся во мнениях. Тестирование вашего URL с обоими стандартами позволяет определить, какие стандартные элементы управления используются в вашей среде. Оба стандарта верны.

Вывод: знайте, какому своду правил следует ваш код — как кодировщик и декодер URL дают вам поведение RFC 3986 в качестве фиксированной контрольной точки.

RFC 3986 нормализация позволяет безопасно декодировать незарезервированные символы с ненужной процентной кодировкой. %41 нормализуется до A. Закодированные зарезервированные символы, такие как %2F, никогда не декодируются; изменение значения нарушает структуру. Органы по стандартизации яростно поддерживают обратную совместимость. Исправление потребует всемирной координации, невозможной спустя десятилетия. Книги по стандартам не разрушают сеть задним числом. Изменение решений по кодированию одновременно ломает миллиарды существующих систем.

Процентное кодирование охватывает три десятилетия тщательной эволюции: от RFC 1738 через RFC 2396 и RFC 3986 до современного стандарта WHATWG URL. Современный код должен соответствовать базовой линии RFC 3986. Старые URL-адреса с более ранней кодировкой остаются действительными. Тестирование туда и обратно гарантирует корректность и совместимость.