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

Вставьте ссылку с процентным кодированием, чтобы прочитать её, или введите текст, чтобы сделать его безопасным для URL. Преобразование идёт по мере ввода, UTF-8 обрабатывается правильно, а если последовательность % повреждена, вы увидите, где именно.

Направление
Каждый %XX превращается обратно в символ, читаемый как UTF-8. Вставьте ссылку целиком, строку запроса или отдельное значение.
Параметры

Вставьте закодированный URL или текст в поле, чтобы декодировать его.

Закодированные URL встречаются в журналах сервера, редиректах и вызовах API. Нужен сервер для собственного сайта или API? Сейчас от 3,02 € в месяц, на выбор: 2 226 серверов.

Разбор URL на части

Схема
https
Хост
shop.example.com
Порт
8443
Путь
/search/r%C3%A9sum%C3%A9
Путь в декодированном виде
/search/résumé
Строка запроса
?q=vps+hosting&sort=price&tag=ssd&tag=nvme&city=M%C3%BCnchen
Фрагмент
#results
Origin
https://shop.example.com:8443

Параметры запроса: 5

  1. q vps hosting
  2. sort price
  3. tag ssd
  4. tag nvme
  5. city München

Имена и значения декодированы, + читается как пробел, как это делает сервер. Имя может встречаться несколько раз.

Работает в вашем браузере: ничего из введённого не отправляется на сервер.

Как работает URL-кодирование

В URL разрешён лишь небольшой набор символов ASCII, и у некоторых из них есть своя роль: / разделяет путь, ? начинает запрос, & и = делят его на параметры, # начинает фрагмент. Любой другой символ или один из этих, если он используется как обычные данные, записывается как % и две шестнадцатеричные цифры на каждый его байт в UTF-8. Это называется процентным кодированием (RFC 3986).

пробел →  %20          (или + в данных формы)
&      →  %26
/      →  %2F
é      →  C3 A9  →  %C3%A9
€      →  E2 82 AC  →  %E2%82%AC

Какие символы кодировать, зависит от того, что вы кодируете. В отдельном значении, например поисковом запросе, нужно кодировать и / ? & = #, иначе URL, в который оно попадёт, сломается: это encodeURIComponent в JavaScript и urlencode в PHP. В целом URL они должны остаться, иначе он перестанет быть ссылкой: это encodeURI. HTML-формы отправляют пробелы как + вместо %20 (application/x-www-form-urlencoded), поэтому + в строке запроса обычно означает пробел.

Декодирование выполняет обратное: каждый %XX становится байтом, а байты читаются как UTF-8. Встроенная в браузер decodeURIComponent при ошибке лишь сообщает «URI malformed». Эта страница называет последовательность и указывает на неё: это % без двух шестнадцатеричных цифр после него или байты, не являющиеся корректным UTF-8, что обычно означает, что текст был закодирован как Latin-1.

Пример

Поисковый запрос «vps hosting/€5» как одно значение превращается в vps%20hosting%2F%E2%82%AC5: пробел — это %20, косая черта — %2F, а знак евро, занимающий в UTF-8 три байта, становится %E2%82%AC. С включённым «Писать пробелы как +» для данных формы получится vps+hosting%2F%E2%82%AC5. Декодирование r%C3%A9sum%C3%A9 даёт résumé, а декодирование caf%E9 завершается ошибкой на %E9, потому что это é в Latin-1, а не в UTF-8.

Вопросы

Что такое URL-кодирование?

URL-кодирование, или процентное кодирование (percent-encoding), записывает символы, которые нельзя использовать в URL или которые имеют там особый смысл, как % и две шестнадцатеричные цифры на каждый байт. Пробел превращается в %20, & — в %26, а é — в %C3%A9. Так любой текст можно безопасно передать внутри ссылки или строки запроса.

Чем отличаются encodeURI и encodeURIComponent?

encodeURI предназначена для всего адреса: она оставляет символы, у которых в URL есть своя роль, например : / ? # & =, чтобы ссылка продолжала работать. encodeURIComponent предназначена для одной части внутри URL, например значения параметра: она кодирует и эти символы, поэтому & в значении не может начать новый параметр. Если сомневаетесь, кодируйте каждое значение через encodeURIComponent, а затем соединяйте их.

Что писать вместо пробела: %20 или +?

Оба варианта верны, но в разных местах. В пути URL пробел должен быть %20. В строке запроса, которую отправляет HTML-форма (application/x-www-form-urlencoded), пробел записывается как +, а настоящий плюс — как %2B. Большинство серверов в строке запроса понимают оба. При декодировании данных формы включите «Читать + как пробел».

Почему при декодировании я получаю «URI malformed»?

Либо после % нет двух шестнадцатеричных цифр, например в обычном «100%» или «%G1», либо байты %XX не являются корректным UTF-8: часто потому, что текст закодирован в Latin-1 (é как %E9) или многобайтовый символ обрезан. Эта страница показывает, какая последовательность неверна и где она находится, чтобы вы могли это исправить.

Как декодировать URL в командной строке или в коде?

В JavaScript: decodeURIComponent(s), после s.replace(/\+/g, ' ') для данных формы. В Python: urllib.parse.unquote(s) или unquote_plus(s) для данных формы. В PHP: rawurldecode($s) или urldecode($s), которая заодно превращает + в пробел. В командной строке с установленным Python: python3 -c "import sys, urllib.parse as u; print(u.unquote(sys.argv[1]))" 'r%C3%A9sum%C3%A9'.