Инструменты разработчика · Кодер и декодер URL
Анатомия URL: объяснение схемы, полномочий, пути, запроса и фрагмента
· Фон
URL-структура веб-стандарты инструменты разработчика
Каждое решение о процентном кодировании зависит от того, в какой части 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.
Знание пяти компонентов и их разделителей позволит вам делать правильный выбор каждый раз, когда вы сталкиваетесь с задачей кодирования.