Кодирование и декодирование URL

RSS

Кодируйте текст для URL и строк запроса (percent-encoding) или декодируйте URL вида %20 обратно в читаемый текст.

Работает на 100% в вашем браузере. Ничего из вставленного не загружается на сервер и не сохраняется.
Текст или закодированный URL
Результат
Готово.

Как пользоваться кодированием и декодированием URL

  1. Выберите Закодировать или Декодировать.
  2. Выберите режим: Компонент (значения параметров) для одного значения параметра запроса или сегмента пути либо Полный URL, чтобы сохранить структуру URL (:, /, ?, &) нетронутой.
  3. Вставьте текст или URL и скопируйте результат.

Всё обрабатывается в вашем браузере. URL часто содержат токены и персональные данные в строке запроса, и ничего из этого не загружается и не сохраняется.

Что такое процентное кодирование?

URL могут содержать только ограниченный набор символов ASCII. Процентное кодирование, определённое в RFC 3986, представляет любой другой байт как знак процента и две шестнадцатеричные цифры. Сначала текст преобразуется в байты UTF-8, затем каждый байт, который нужно экранировать, записывается как %XX:

café & crème   →   caf%C3%A9%20%26%20cr%C3%A8me

Здесь é — это два байта UTF-8 (C3 A9), пробел превращается в %20, а амперсанд — в %26.

Зарезервированные и незарезервированные символы

ГруппаСимволыЗначение
НезарезервированныеA–Z a–z 0–9 - . _ ~Никогда не требуют кодирования.
Зарезервированные: gen-delims: / ? # [ ] @Разделяют основные части URL.
Зарезервированные: sub-delims! $ & ' ( ) * + , ; =Разделяют данные внутри части, например & и = в строках запроса.

Зарезервированные символы нужно кодировать, когда они выступают как данные, а не как разделители. Поиск R&D нужно отправлять как q=R%26D; иначе сервер увидит второй параметр с именем D.

encodeURIComponent и encodeURI

В JavaScript есть две функции, и выбор не той функции — частый источник ошибок:

  • encodeURIComponent() кодирует всё, кроме A–Z a–z 0–9 - _ . ! ~ * ' ( ). Используйте её для отдельных значений: параметров запроса, сегментов пути, данных фрагмента.
  • encodeURI() дополнительно оставляет нетронутыми ; , / ? : @ & = + $ #, поэтому её можно применять к полному URL, не нарушая его структуру. Она не защитит значение, содержащее & или #.
encodeURI("https://example.com/a b?q=R&D")
// "https://example.com/a%20b?q=R&D"      (& не тронут)

"https://example.com/search?q=" + encodeURIComponent("R&D")
// "https://example.com/search?q=R%26D"

Ещё лучше поручить построение строк запроса URLSearchParams или URL-библиотеке вашего языка.

Частые ловушки

+ или %20

HTML-формы, отправляемые как application/x-www-form-urlencoded, кодируют пробел как +. В URL по RFC 3986 + — это обычный знак плюс, а пробел — %20. Декодер, который не знает, какое соглашение использовалось, может превратить C++ в C или оставить + вместо пробелов. Чтобы не ошибиться, кодируйте настоящий знак плюс как %2B.

Python:  urllib.parse.quote("a b&c")       → a%20b%26c
         urllib.parse.quote_plus("a b&c")  → a+b%26c

Двойное кодирование

Кодирование уже закодированной строки экранирует сами знаки процента: %20 превращается в %2520. Обычно это происходит, когда значение кодируется вашим кодом и повторно фреймворком или HTTP-клиентом. Если вы видите %25 в URL, подозревайте двойное кодирование. Двойное декодирование не менее вредно: оно может превратить буквальное %41 в пользовательских данных в A.

Кодирование всего URL как компонента

Применение encodeURIComponent к полному URL экранирует :// и каждый /, давая https%3A%2F%2F.... Это правильно, только когда сам URL является значением параметра, например redirect_uri.

Советы

  • Шестнадцатеричные цифры в процентном кодировании нечувствительны к регистру, но RFC 3986 рекомендует верхний регистр (%2F, а не %2f).
  • Интернационализированные доменные имена не кодируются процентным кодированием; вместо этого они используют Punycode (xn--).
  • Нужно передать двоичные данные в URL? URL-безопасный Base64 компактнее, чем процентное кодирование каждого байта.
  • Посмотрите, как сервер обрабатывает ваш закодированный запрос, с помощью проверки HTTP-заголовков.

Часто задаваемые вопросы

Почему пробел кодируется то как +, то как %20?

+ пришёл из кодирования HTML-форм, которое используется в строках запроса и телах POST; %20 — общее кодирование по RFC 3986, допустимое в любом месте URL. Если сомневаетесь, используйте %20.

Какие символы никогда не нужно кодировать?

Незарезервированный набор: буквы, цифры, дефис, точка, подчёркивание и тильда. Всё остальное следует кодировать, если оно входит в значение.

Является ли кодирование URL мерой безопасности?

Нет. Оно лишь делает данные синтаксически безопасными внутри URL и полностью обратимо. Само по себе оно не скрывает данные и не предотвращает инъекции.

Как декодировать URL с последовательностями %uXXXX?

%uXXXX — нестандартный формат, создаваемый устаревшей функцией JavaScript escape(). Стандартные декодеры его отвергают; его нужно преобразовывать отдельно.

Обновлено

Скопировано в буфер обмена