Русский

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

Анатомия URL: объяснение схемы, полномочий, пути, запроса и фрагмента

· Фон

URL-структура веб-стандарты инструменты разработчика

Пять компонентов URL, помеченных разделителями.
Оригинальная векторная иллюстрация ToolAcre

Каждое решение о процентном кодировании зависит от того, в какой части URL находится символ. В этом посте названы пять компонентов из RFC 3986, показано, что означает каждый разделитель и почему фрагмент никогда не достигает сервера.

Почему один и тот же # в одном месте подходит, а в другом уничтожает ссылку — компонентный вопрос, а не символьный вопрос

Символ решетки (#) в URL означает совершенно разные вещи в зависимости от того, где он появляется. Внутри значения строки запроса, например ?search=C%23sharp, оно должно быть закодировано в %23, чтобы быть безопасным. В конце URL, например https://example.com/page#section,, он отмечает разделитель фрагмента и все, что после него, является фрагментом. Один персонаж, два контекста, два разных значения. Вот почему решения о кодировании зависят от знания того, с какой частью URL вы работаете.

Вопросительный знак (?) также имеет двойственную природу. Внутри значения пути или запроса оно должно быть закодировано как %3F, чтобы оно отображалось как данные. Как буквальный символ между путем и строкой запроса, это структурный синтаксис. Понимание этих пяти компонентов — схемы, полномочий, пути, запроса и фрагмента — является основой правильной обработки URL.

Пять компонентов: схема, авторитет, путь, запрос, фрагмент — и разделители, которые их разделяют.

RFC 3986 формально определяет URL-адреса как имеющие пять компонентов: схему, полномочия, путь, запрос и фрагмент, разделенные определенными разделителями. Сначала идет схема, затем ://,, затем полномочия, затем /,, затем путь, затем ?, затем запрос, затем #, затем фрагмент. Не все компоненты присутствуют в каждом URL. Минимальный URL может содержать только схему и путь, например «mailto:user@example.com». Полный URL включает все пять.

Каждый компонент имеет свои собственные правила синтаксиса. Двоеточие зарезервировано в схеме, косая черта в пути, амперсанд в запросе. Зарезервированные символы требуют кодирования, когда они появляются в виде данных: косая черта в значениях пути становится %2F.

Внутри полномочий — информация о пользователе, хосте и порте, а также почему там зарезервированы @ и :.

Компонент полномочий содержит сетевой адрес ресурса: имя пользователя, пароль, имя хоста и порт. Формат: [userinfo@]хост[:порт]. Информация о пользователе и хост разделяются символом @; хост и порт разделяются :. Эти символы @ и : зарезервированы для разграничения этих подкомпонентов. Если у вас есть имя пользователя, содержащее символ @, перед объединением оно должно быть закодировано в процентах. Например, «user@email.com:пароль» в качестве имени пользователя будет выглядеть как «user%40email.com:пароль» перед последней @.

Имя хоста может быть зарегистрированным доменом, например example.com, IP-адресом в десятичном формате с точками, например 192.0.2.1, или адресом IPv6, заключенным в скобки, например [::1]. Порт не является обязательным; если он опущен, схема определяет значение по умолчанию (80 для http, 443 для https и т. д.). Часть userinfo редко используется в современных URL-адресах, но остается частью синтаксиса.

Сегменты пути и значение / — иерархическая структура и разрешение точечных сегментов.

Путь представляет собой последовательность сегментов, разделенных косой чертой. Путь /a/b/c состоит из трех сегментов: a, b и c. Каждый сегмент может содержать незарезервированные символы, символы с процентной кодировкой или определенные зарезервированные символы, которые безопасны в этом контексте. Косая черта внутри сегмента должна быть закодирована как %2F, чтобы избежать путаницы с разделителями сегментов. Путь иерархичен; подразумевается, что a — это местоположение, тогда a/b является более конкретным.

Пути также поддерживают специальные сегменты с точками: одна точка (.) означает «текущий каталог», а две точки (..) означают «родительский каталог». Путь типа ../../etc/passwd разрешается вверх. Современные URL-адреса и HTTP не используют их, но они существуют в синтаксисе. Сегмент пути, содержащий буквальную точку или двойную точку, должен быть закодирован в процентах, если буквальное значение точки не предусмотрено.

Запрос и фрагмент — соглашения «ключ-значение» и почему фрагмент остается в браузере

Строка запроса следует по пути и начинается с ?. Традиционно это серия пар ключ=значение, разделенных знаком &, хотя синтаксис на самом деле неструктурирован — в запрос может входить что угодно. Если у вас есть значение, содержащее & или =, эти символы должны быть закодированы в процентах, чтобы их нельзя было принять за разделители. Запрос отправляется на сервер; сервер решает, что с ним делать.

Фрагмент следует за запросом и начинается с #. Все, что после #, является фрагментом и никогда не доходит до сервера. Браузер обрабатывает фрагмент локально, обычно для перехода к именованной привязке или для указания состояния в одностраничном приложении. Поскольку фрагмент никогда не достигает сервера, считается, что URL с другим фрагментом указывает на тот же ресурс.

Рабочий пример: анализ длинного реального объекта URL — маркировка каждого компонента и каждого разделителя.

Возьмите URL "https://user:pass@example.com:8080/path/to/page?search=hello&sort=date#results".. Схема — https. Полномочия — пользователь:pass@example.com:8080, разделенные на информацию пользователя (user:pass), хост (example.com) и порт (8080). Путь — /path/to/page, с сегментами пути, до и страницы. Запрос — search=hello&sort=date, содержащий два параметра. Фрагмент — результаты. Введите этот URL в кодировщик и декодер URL, чтобы увидеть, как инструмент маркирует и кодирует каждый компонент.

Если поиск содержал &, например ?search=R&D, при правильном кодировании он становится ?search=R%26D. Символы с процентной кодировкой не создают визуальных границ в тексте, поэтому для правильного анализа абсолютно необходимо тщательное кодирование и декодирование.

Чего это не касается — относительного разрешения ссылок и специальных схем, таких как mailto: и data:

Относительные ссылки, такие как «../page» или «?query=value», действительны внутри HTML и интерпретируются относительно текущего документа, но имеют свои собственные правила разрешения. Специальные схемы, такие как mailto:, data: и file:, следуют совершенно другим правилам и не являются стандартными абсолютными URL-адресами.

В этом посте основное внимание уделяется только стандартной абсолютной структуре URL, продемонстрированной инспектором. Относительным ссылкам требуется база URL, прежде чем их компоненты можно будет интерпретировать, в то время как такие схемы, как mailto и data, не имеют одинаковой формы полномочий и путей. Разделение этих случаев предотвращает слепое применение правила, полученного из адреса HTTPS, к синтаксису с другими разделителями, шагами разрешения или поведением транспорта.

Вывод: изучите компонент перед кодированием — как режимы однозначного и целого адреса кодера и декодера URL сопоставляются с этой структурой.

Кодируемый вами компонент определяет, какие символы необходимо экранировать, а какие безопасны. Косая черта в пути является буквальным синтаксисом, поэтому косая черта в значении должна быть %2F. В запросах & и = должны быть закодированы, если они присутствуют в значениях. Кодер и декодер URL имеет два режима: «компонент» для кодирования одного значения и «весь адрес» для полного URL. Используйте режим компонента при создании URL-адресов путем объединения частей; используйте режим всего адреса для проверки существующего URL.

Знание пяти компонентов и их разделителей позволит вам делать правильный выбор каждый раз, когда вы сталкиваетесь с задачей кодирования.