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

URL encode и decode: кириллица, пробелы и спецсимволы в адресе, разбор параметров, windows-1251.

Данные обрабатываются в браузере и никуда не отправляются

Режим
Способ
Кодировка
Здесь появится результат

Как пользоваться

Выберите режим, вставьте текст слева - результат появляется сразу, без кнопок. В режиме «Кодировать» текст превращается в безопасную для адреса строку с %-последовательностями, в режиме «Декодировать» - наоборот. Если нужна обратная операция, нажмите «Поменять местами»: результат станет входными данными, а режим переключится. В режиме декодирования адрес дополнительно разбирается на части: протокол, хост, путь и таблица параметров запроса - уже раскодированные.

Способ кодирования определяет, какие символы остаются как есть. Для значения параметра или сегмента пути берите «Компонент»: он закодирует все служебные знаки (/ ? & = # и другие). «Адрес целиком» подходит только для готового адреса, у которого нужно экранировать пробелы и кириллицу, не ломая https://, ? и &. «Строгий RFC 3986» кодирует ещё и ! * ' ( ) - это поведение rawurlencode в PHP. «Форма» кодирует пробел знаком «+», как это делают HTML-формы и urlencode в PHP. Кодировка по умолчанию - UTF-8, это стандарт; windows-1251 и KOI8-R нужны только для старых сайтов.

Справочник символов

СимволКодРоль в адресе
пробел%20В данных формы заменяется на «+»
!%21Служебный символ (sub-delim), в encodeURIComponent не кодируется
"%22Ограничитель значений в HTML
#%23Начало якоря (fragment), на сервер не передаётся
$%24Служебный символ (sub-delim)
%%25Признак закодированного символа, сам кодируется как %25
&%26Разделитель параметров запроса
'%27Служебный символ (sub-delim), в encodeURIComponent не кодируется
( )%28 %29Служебные символы (sub-delim)
*%2AСлужебный символ (sub-delim)
+%2BВ данных формы означает пробел, в пути - обычный плюс
,%2CРазделитель значений
/%2FРазделитель сегментов пути
:%3AОтделяет протокол, порт и пароль
;%3BРазделитель параметров
< >%3C %3EУгловые скобки HTML, всегда кодируются
=%3DОтделяет имя параметра от значения
?%3FНачало строки запроса
@%40Отделяет пользователя от хоста
[ ]%5B %5DАдреса IPv6 в хосте
\ ^ `%5C %5E %60Небезопасные символы, всегда кодируются
{ | }%7B %7C %7DНебезопасные символы, всегда кодируются
~%7EНе кодируется по RFC 3986 (старый urlencode в PHP кодировал)
я%D1%8FЛюбая не-ASCII буква: два байта UTF-8, две последовательности

Способы кодирования

Режим на сайтеНе кодируютсяПробелАналоги в языках
КомпонентA-Z a-z 0-9 - _ . ! ~ * ' ( )%20JavaScript: encodeURIComponent; C#: Uri.EscapeDataString (почти)
Адрес целикомкак «Компонент» плюс ; , / ? : @ & = + $ #%20JavaScript: encodeURI
Строгий RFC 3986A-Z a-z 0-9 - _ . ~%20PHP: rawurlencode; Python: urllib.parse.quote(s, safe='')
ФормаA-Z a-z 0-9 * - _ .+PHP: urlencode; Python: quote_plus; Java: URLEncoder; HTML-формы и URLSearchParams

Как сделать то же в коде

ЯзыкКодированиеДекодирование
JavaScriptencodeURIComponent(s)decodeURIComponent(s)
PHPrawurlencode($s) / urlencode($s)rawurldecode($s) / urldecode($s)
Pythonurllib.parse.quote(s, safe='') / quote_plus(s)urllib.parse.unquote(s) / unquote_plus(s)
JavaURLEncoder.encode(s, StandardCharsets.UTF_8)URLDecoder.decode(s, StandardCharsets.UTF_8)
C#Uri.EscapeDataString(s)Uri.UnescapeDataString(s)
Gourl.QueryEscape(s) / url.PathEscape(s)url.QueryUnescape(s) / url.PathUnescape(s)
RubyERB::Util.url_encode(s)CGI.unescape(s)
curlcurl --data-urlencode "q=привет"-

Частые ошибки

Вот что чаще всего идёт не так при работе с URL-кодированием:

Кодируют весь адрес как компонент

Если пропустить через encodeURIComponent адрес целиком, он превратится в https%3A%2F%2Fexample.com%2F..., и ссылка перестанет работать: «://», «/», «?» и «&» потеряют служебный смысл. Кодируйте по отдельности значения параметров и сегменты пути, а не готовый адрес.

Кодируют уже закодированное

Повторное кодирование превращает %20 в %2520 - знак «%» сам кодируется. Если в результате видите %25 там, где ждали пробел или букву, текст закодирован дважды: декодируйте его столько раз, сколько нужно (инструмент подскажет).

Плюс вместо пробела в пути

«+» означает пробел только в данных формы (после «?»). В пути адреса плюс - обычный символ, и пробел там обязан быть %20. Поэтому для кодирования сегментов пути выбирайте «Компонент», а не «Форма».

Плюс в данных не закодирован

Значение a+b, переданное в параметре как есть, сервер прочитает как «a b». Чтобы сохранить плюс, его нужно закодировать как %2B - все способы, кроме «Адрес целиком», так и делают.

Не закодирован амперсанд или знак равенства

Значение «Tom & Jerry» без кодирования разорвёт параметры: сервер увидит параметр «Tom » и отдельный параметр « Jerry». Все значения нужно кодировать, чтобы & и = оказались %26 и %3D.

Не та кодировка

Современные сайты ждут UTF-8: «я» - это %D1%8F. Старые (и часть российских CMS) используют windows-1251, где та же буква - %FF. Если вместо текста получаются символы «�» или «РїСЂРёРІРµС‚», переключите кодировку - инструмент сам подскажет подходящую.

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

Что такое URL-кодирование (процентное кодирование)?

Адрес (URL) может состоять только из ограниченного набора символов ASCII: латинских букв, цифр и нескольких знаков. Всё остальное - пробелы, кириллица, иероглифы, эмодзи, а также символы, которые в адресе имеют особый смысл, - записывается последовательностью %XX, где XX - шестнадцатеричное значение байта.

Например, пробел - %20, знак вопроса - %3F, а русская буква «я» в UTF-8 занимает два байта и превращается в %D1%8F. Способ описан в стандарте RFC 3986 и называется percent-encoding. Он нужен, чтобы любые данные можно было безопасно передать в адресной строке, не нарушив структуру адреса.

Какие символы кодируются, а какие остаются как есть?

Без кодирования всегда остаются «безопасные» символы (unreserved): латинские буквы A-Z и a-z, цифры 0-9 и знаки - _ . ~.

Зарезервированные символы (reserved) ! * ' ( ) ; : @ & = + $ , / ? # [ ] имеют в адресе служебную роль. Если они часть данных, их нужно кодировать, если служебные - оставлять. Все остальные символы - пробел, кавычки, < > \ ^ ` { | }, кириллица и любые не-ASCII знаки - кодируются всегда. Полная таблица символов с кодами приведена выше, в разделе «Справочник символов».

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

encodeURIComponent (режим «Компонент») кодирует всё, кроме букв, цифр и - _ . ! ~ * ' ( ). Его используют для значений параметров и сегментов пути.

encodeURI (режим «Адрес целиком») дополнительно оставляет служебные символы ; , / ? : @ & = + $ #, поэтому подходит только для готового адреса, в котором нужно заменить пробелы и кириллицу.

rawurlencode в PHP (режим «Строгий RFC 3986») кодирует всё, кроме букв, цифр и - _ . ~. urlencode в PHP (режим «Форма») делает то же, но пробел заменяет на «+», как браузер при отправке формы. Точное сравнение - в таблице «Способы кодирования».

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

Исторически сложились два формата. По RFC 3986 пробел везде кодируется как %20. А формат application/x-www-form-urlencoded, в котором браузеры отправляют данные HTML-форм, заменяет пробел знаком «+».

Поэтому «+» означает пробел только в строке запроса, составленной формой (после «?»), а в пути адреса «+» - обычный плюс. Если сомневаетесь, используйте %20: его правильно понимают в обоих местах. А чтобы передать сам знак плюс, всегда кодируйте его как %2B.

Нужно ли кодировать адрес целиком?

Как правило, нет. Кодировать нужно отдельные части - значения параметров и сегменты пути - до того, как вы соберёте из них адрес. Если закодировать готовый адрес как компонент, исчезнет его структура: https://site.ru/a?b=c превратится в https%3A%2F%2Fsite.ru%2Fa%3Fb%3Dc, и это уже не ссылка.

Исключение - когда адрес целиком является значением параметра другого адреса (например, redirect=https%3A%2F%2Fsite.ru%2Fa%3Fb%3Dc): тогда кодировать его как компонент как раз нужно.

Как закодировать кириллицу в URL?

Выберите режим «Компонент» (для параметров и сегментов пути) или «Адрес целиком» (для готовой ссылки) и кодировку UTF-8. Каждая русская буква занимает в UTF-8 два байта, поэтому превращается в две последовательности: «привет» - %D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82. Браузеры показывают такой адрес в читаемом виде, но отправляют на сервер закодированным.

Доменные имена с кириллицей кодируются иначе - не процентами, а по алгоритму Punycode: «пример.рф» превращается в xn--e1afmkfd.xn--p1ai. Это делает сам браузер при обращении к сайту.

Что такое двойное кодирование и как его исправить?

Это ситуация, когда уже закодированную строку закодировали ещё раз: знак «%» превратился в %25, и %D0 стал %25D0. Признак - в результате декодирования вы снова видите %-последовательности, а не буквы.

Исправить просто: декодируйте строку повторно. Инструмент сам замечает такой случай и показывает кнопку «Декодировать ещё раз». Чтобы не создавать проблему, кодируйте данные ровно один раз - в том месте, где собираете адрес.

Почему при декодировании получаются «кракозябры» и при чём здесь windows-1251?

Процентное кодирование записывает байты, а то, какие это буквы, определяет кодировка. Современные сайты используют UTF-8 (буква «п» - %D0%BF), но старые российские сайты и некоторые CMS - windows-1251 (та же буква - %EF), реже KOI8-R. Если выбрана не та кодировка, вместо текста получаются символы замены «�» или нечитаемый набор вроде «РїСЂРёРІРµС‚».

Переключите кодировку - инструмент при ошибке сам определяет, что строка больше похожа на windows-1251 или KOI8-R, и предлагает её одной кнопкой.

Как кодировать и декодировать URL в JavaScript, PHP, Python и других языках?

В JavaScript - encodeURIComponent и decodeURIComponent; в PHP - rawurlencode/rawurldecode и urlencode/urldecode; в Python - urllib.parse.quote и unquote; в Java - URLEncoder.encode и URLDecoder.decode с явным указанием UTF-8; в C# - Uri.EscapeDataString и Uri.UnescapeDataString; в Go - url.QueryEscape и url.QueryUnescape.

Полная таблица с вызовами для каждого языка приведена выше, в разделе «Как сделать то же в коде». Всегда указывайте кодировку явно: если библиотека берёт её из настроек системы, на другом сервере результат может отличаться.

Можно ли использовать URL-кодирование для защиты данных?

Нет. Процентное кодирование - это не шифрование и не защита: любой человек раскодирует строку за секунду, в том числе этим же инструментом. Оно лишь делает данные безопасными для передачи в адресе. Пароли и токены в адресной строке небезопасны сами по себе: они остаются в истории браузера, журналах серверов и заголовке Referer.

Какая максимальная длина URL?

Стандарт не ограничивает длину адреса, но на практике пределы есть: браузеры и поисковые системы стабильно работают примерно до 2000 символов, веб-серверы по умолчанию принимают строку запроса порядка 8 КБ (в nginx и Apache это настраивается). Учтите, что кодирование удлиняет адрес: каждая русская буква превращается в 6 символов (%D0%BF), поэтому длинные тексты лучше передавать в теле POST-запроса, а не в адресе.

Почему часть адреса после # не попадает на сервер?

Всё после знака # - якорь (fragment) - обрабатывается только браузером и в запросе к серверу не отправляется. Поэтому его нельзя использовать для передачи данных на сервер, а в значениях параметров символ # обязательно кодируется как %23, иначе остаток строки будет отрезан.

Отправляются ли мои данные на сервер?

Нет - 100%. Сайт целиком статический, у него нет серверной части, которая могла бы принять текст. Кодирование и декодирование выполняются прямо в вашем браузере.

Похожие инструменты

Курс «Проектирование API и интеграций»

Глубокое погружение в REST, gRPC, SOAP, проектирование баз данных и брокеры сообщений (Kafka, RabbitMQ). Делегирование рутины нейросетям (ИИ). Перестанете бояться технических собеседований и начнете говорить с разработчиками на одном языке. Курс собран так, чтобы пробить зарплатный потолок и вырасти в грейде - ученики тому подтверждение.

Перейти к курсу на Stepik