Форма URL
Каждый абсолютный URL следует одному и тому же каркасу:
scheme://user:password@host:port/path?query#fragment
Большинство URL используют лишь горсть этих слотов, но грамматика всегда допускает все их. Чтение URL во многом сводится к тому, чтобы знать, где заканчивается один компонент и начинается следующий, что решается разделителями ://, @, :, /, ? и #.
Компонент за компонентом
Протокол (схема) определяет, как получить ресурс — https:, mailto:, ftp:. Обратите внимание, что парсер WHATWG включает закрывающее двоеточие в это значение, что удивляет тех, кто сравнивает его со строкой "https".
Имя пользователя и пароль — это устаревшая секция userinfo. Браузеры всё ещё разбирают их, но удаляют из запросов и часто предупреждают, потому что встраивание учётных данных в URL раскрывает их в истории, логах и заголовках referrer. Воспринимайте их присутствие в URL, который вы не писали, как фишинговый сигнал.
Имя хоста — это только домен или IP-адрес. Хост — это имя хоста плюс порт, когда присутствует нестандартный порт, поэтому два этих поля здесь часто выглядят одинаково.
Порт пуст, когда URL использует порт по умолчанию для схемы — 443 для https, 80 для http. Парсер нормализует это: example.com:443/ сообщает пустой порт, потому что 443 не добавляет информации.
Путь — это всё от первого / до запроса. Это единственный компонент, который никогда не пуст для URL http(s); голое происхождение получает путь /.
Строка запроса начинается с ? и несёт параметры. Фрагмент начинается с # и является единственной частью, которая никогда не отправляется на сервер — он обрабатывается чисто на стороне клиента, поэтому одностраничные приложения когда-то использовали его для маршрутизации, а токен доступа во фрагменте остаётся вне серверных логов.
Происхождение — это значимая для безопасности тройка схемы, хоста и порта. Два URL имеют общее происхождение только когда совпадают все три, и именно на этом основаны политика одного источника и решения CORS.
Почему парсер строг
Парсер WHATWG URL принимает только абсолютные URL. У example.com/page нет схемы, поэтому он не может быть разобран сам по себе — у парсера нет способа узнать, имели ли вы в виду example.com/page или относительный путь. Реальный код разрешает относительные ссылки относительно базового URL; этот инструмент намеренно требует абсолютной формы, чтобы то, что вы видите, было однозначным.
Нормализация, которую вы заметите
Парсер не возвращает исходную строку. Он приводит схему и хост к нижнему регистру, разрешает сегменты . и .. в пути, отбрасывает порты по умолчанию и преобразует интернационализированные доменные имена в их форму Punycode, поэтому münchen.de сообщает имя хоста xn--mnchen-3ya.de. Это возможность: она показывает URL таким, как сетевой стек действительно будет его трактовать, а не таким, как он был набран.
Повторяющиеся параметры
Строка запроса может законно повторять ключ, как в ?tag=a&tag=b. Никакая спецификация не говорит, что это значит — некоторые фреймворки берут первое значение, некоторые последнее, некоторые собирают массив. Таблица здесь перечисляет каждое вхождение по порядку, чтобы вы видели точно то, что было отправлено, а не свёрнутый вид.