Декодер и кодировщик URL

%E4%B8%AD%E6%96%87 и подобные ему процентные последовательности можно вернуть здесь в читаемый вид; работает и обратное — текст, пробелы и спецсимволы превращаются в форму, которую безопасно положить в URL. Поддерживаются кодировки UTF-8 и GBK, распознаётся плюс в роли пробела, а если вставить ссылку целиком, страница вдобавок разложит её по параметрам запроса и раскодирует каждый. Всё выполняется локально в браузере, ничего никуда не отправляется.
Закодированный URL или параметр
Кодировка
Примечания:
1. Если во вставленном есть %XX , страница сама переключается на декодирование, если нет — на кодирование. После того как вы нажали кнопку режима руками, угадывать она перестаёт.
2. Испорченная последовательность % не рушит всю строку: эти несколько символов остаются как есть, а остальное декодируется как обычно.
3. Вопросительные знаки или квадратики на выходе почти всегда значат, что исходный сайт использовал GBK, — переключитесь на GBK и попробуйте снова.
4. Если вставить ссылку целиком, ниже отдельно перечисляются схема, хост, путь и каждый параметр запроса.
5. URL-кодирование — не шифрование: развернуть его может кто угодно, так что прятать в нём параметры бессмысленно.

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

Что такое URL-кодирование и почему текст превращается в %E4%B8%AD

Стандарт URL (RFC 3986) разрешает только латинские буквы, цифры и горстку символов. Кириллица, иероглифы, пробелы, кавычки в этот список не входят. Чтобы поместить их в ссылку, их сначала переводят в байты какой-нибудь кодировкой, а затем каждый байт записывают знаком процента и двумя шестнадцатеричными цифрами — это и есть процентное кодирование, оно же URL-кодирование. Символ 中 занимает в UTF-8 три байта, E4 B8 AD, которые записываются как %E4%B8%AD. Так что вереница %E4%B8... — это не крякозябры и не шифр, а просто другая запись того же текста; идущие по три %XX подряд почти наверняка означают иероглифы в UTF-8, а кириллица занимает по два байта и выглядит как %D0../%D1..

encodeURIComponent или encodeURI — что выбрать

Это то, в чём при написании кода ошибаются чаще всего. encodeURIComponent кодирует и : / ? # & =структурные символы, и потому годится для одного значения параметра; encodeURI их оставляет и подходит для уже собранной целиком ссылки. Ошибка здесь даёт вполне осязаемый результат: передайте весь URL в encodeURIComponent, https:// превратится в https%3A%2F%2F, и ссылка попросту сломается. Наоборот, взяв encodeURI для значения параметра, в котором и так есть & (скажем, поисковый запрос «A&B»), вы получите вот что: этот & останется нетронутым, сервер примет его за разделитель, и один параметр приедет к нему как два. Кодировщик выше умеет и то и другое; по умолчанию выбран режим для значения параметра.

URL-кодирование — не шифрование

URL-кодирование, как и Base64, — это кодирование, а не шифрование: правила полностью открыты, ключа нет, и любой, у кого есть строка, разворачивает её в одно действие — эта страница ровно этим и занимается. Смысл его в том, чтобы спецсимволы благополучно прошли по каналу под названием URL, и никакой секретности он не даёт. Поэтому номер заказа, телефон или внутренний идентификатор, пропущенный через URL-кодирование перед вставкой в ссылку, не защищён ничем: и в адресной строке, и в логах сервера, и в заголовке Referer лежит открытый текст. Если нужна необратимость, посмотрите соседний инструмент: SHA-256. А чувствительные параметры передавайте методом POST поверх HTTPS. И, к слову, «расшифровки URL» попросту не существует — правильное слово «декодирование».

Три ловушки: плюс, %20 и крякозябры

У пробела две записи. Отправка форм использует application/x-www-form-urlencoded и кодирует пробел как +, а в путях и современных API обычно берут %20. Загвоздка в том, что в JavaScript decodeURIComponent не понимает + вовсе и оставляет плюс как есть — отсюда и переключатель выше, по умолчанию читающий его как пробел. И наоборот: если плюс в содержимом настоящий (скажем, 1+1), при кодировании он станет %2B, и это правильно.

Вторая ловушка — кодировка. Сегодня по умолчанию везде UTF-8, но немало старых сайтов и систем работают на GBK, где 中 — это два байта, %D6%D0. Раскодируйте содержимое в GBK как UTF-8 — и получите вопросительные знаки или квадратики. На стороне декодирования эта страница позволяет переключиться на GBK; сторона кодирования работает только с UTF-8, потому что больше браузер сам ничего и не умеет.

Соответствие имён функций по языкам. В PHP urlencode превращает пробел в +, rawurlencode даёт %20; обратные им — urldecode / rawurldecode; в Java URLEncoder.encode(s, "UTF-8") работает по правилам форм, а значит, тоже +; Python использует urllib.parse.quote / unquote, причём только quote_plus выдаёт +; а в JavaScript есть один encodeURIComponent / decodeURIComponent, и он всегда даёт %20. Когда фронтенд с бэкендом не сходятся, дело почти всегда в этом плюсе.

Частые вопросы

Почему текст в ссылке превратился в %E4%B8%AD?

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

Раскодировал, а там всё те же крякозябры или сплошные вопросительные знаки — что делать?

Переключитесь на GBK и раскодируйте ещё раз. По умолчанию здесь UTF-8, но немало старых сайтов и систем работают на GBK: один и тот же символ 中 в UTF-8 — это %E4%B8%AD, а в GBK — %D6%D0, и при неверной кодировке вопросительные знаки или квадратики неизбежны. Простой способ прикинуть на глаз: %XX по три подряд — почти наверняка UTF-8; по два, где первый байт попадает в диапазон %A1%FE — скорее всего, GBK.

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

Первая кодирует ещё и : / ? # & = , поэтому она — для одного значения параметра; вторая эти структурные символы сохраняет и предназначена для ссылки целиком. Собирая URL, почти всегда следует брать encodeURIComponent для каждого значения параметра, а склеивать их самому через ? и &. Применять encodeURI ко всему URL уместно ровно в одном случае: ссылка уже собрана, и нужно лишь узаконить попавшие в неё нелатинские символы и пробелы.

Плюс — это пробел или всё-таки плюс?

Смотря по контексту, и именно здесь чаще всего ошибаются. Отправка форм (application/x-www-form-urlencoded) кодирует пробел как +, поэтому в строке запроса + обычно и означает пробел; а вот в пути или в современном API тот же + — как правило, настоящий плюс. В JavaScript decodeURIComponent такого преобразования не делает вовсе. Эта страница по умолчанию читает + как пробел; если плюс в вашем содержимом настоящий (скажем, C++), снимите эту галочку перед декодированием.

Откуда берётся «URI malformed» или ошибка при декодировании?

Значит, в строке есть некорректная процентная последовательность: после % идут не две шестнадцатеричные цифры либо байты не складываются в допустимый UTF-8. Обычно при копировании потерялся символ или содержимое закодировали дважды (%25E4 и тому подобное, где %25 — это сам % , так что до настоящего текста доходишь ещё одним проходом). Страница из-за этого не роняет всю строку целиком: некорректный фрагмент остаётся как есть, остальное декодируется как обычно, и вы сразу видите, какой именно кусок сломан.

Защищает ли URL-кодирование параметры в ссылке?

Нет, к шифрованию оно не имеет никакого отношения. Правила общедоступны, развернуть их может кто угодно в одно действие, и после кодирования ваш телефон или номер заказа всё так же лежат открытым текстом в адресной строке, в истории браузера, в логах сервера и в заголовке Referer. Чтобы действительно защитить чувствительный параметр, отправляйте его методом POST поверх HTTPS, проверяйте права на сервере или замените его результатом необратимого преобразования — это хеш. А «расшифровка URL» — просто неверный термин: правильно говорить «декодирование».

Ссылки, которые я вставляю, куда-нибудь отправляются?

Нет. Кодирование и декодирование выполняют встроенные в браузер encodeURIComponent / TextDecoder, всё считается на вашем устройстве и сразу выводится на экран, ни один байт браузер не покидает. Отключите сеть после загрузки страницы — инструмент продолжит работать; это самый прямой способ убедиться. Ссылки с токенами и номерами заказов можно вставлять спокойно. Подробности здесь:Политика конфиденциальности.

Какие ещё есть инструменты для разработчиков?

Да. Форматирование JSON разворачивает ответ API в читаемое дерево, Кодирование и декодирование Base64 берёт на себя другую повсеместную кодировку, Конвертер меток времени превращает 10- и 13-значные числа из логов в понятное человеку время, а MD5 и SHA-256 считают контрольные хеши. Все они точно так же работают локально и ничего никуда не отправляют.