URL-кодирование против Base64: в чём разница?
URL-кодирование (percent-encoding) преобразует специальные символы в URL в формат %XX согласно RFC 3986. Base64 преобразует двоичные данные в текстовую строку с помощью 64 ASCII-символов согласно RFC 4648. Они решают разные задачи и не взаимозаменяемы.
Что такое URL-кодирование?
URL-кодирование, также называемое percent-encoding, определено в RFC 3986 как механизм представления символов в URI, которые запрещены или имеют специальное значение. Каждый кодируемый символ преобразуется в один или несколько байтов (в кодировке UTF-8), и каждый байт представляется знаком процента (%), за которым следуют две шестнадцатеричные цифры в верхнем регистре.
Например, символ пробела превращается в %20, амперсанд — в %26, а не-ASCII символ, такой как знак евро, — в %E2%82%AC (три байта UTF-8, каждый из которых кодируется через процент).
// Примеры URL-кодирования на JavaScript
encodeURIComponent('hello world'); // "hello%20world"
encodeURIComponent('price=10&qty=2'); // "price%3D10%26qty%3D2"
encodeURIComponent('cafe'); // "caf%C3%A9"
URL-кодирование специально предназначено для того, чтобы делать URL безопасными и корректными. Оно кодирует только символы, которые не разрешены или имеют зарезервированное значение в URI, оставляя буквенно-цифровые символы и несколько безопасных знаков нетронутыми.
Что такое Base64?
Base64, определённое в RFC 4648, — это схема кодирования из двоичного вида в текстовый, которая представляет двоичные данные с помощью набора из 64 ASCII-символов: A-Z, a-z, 0-9, + и /, где = используется для дополнения (padding). Каждые три байта входных данных дают четыре символа на выходе.
Base64 было разработано для передачи двоичных данных по каналам, которые надёжно поддерживают только текст, таким как электронная почта (MIME) или встраивание данных в XML/JSON. Оно не привязано к URL и кодирует все входные байты, а не только специальные символы.
// Примеры кодирования Base64 на JavaScript
btoa('hello world'); // "aGVsbG8gd29ybGQ="
btoa('price=10&qty=2'); // "cHJpY2U9MTAmcXR5PTI="
// Для строк в Unicode сначала преобразуйте их в UTF-8
function toBase64(str) {
return btoa(unescape(encodeURIComponent(str)));
}
toBase64('cafe'); // "Y2Fmw6k="
Существует также URL-безопасный вариант Base64 (Base64url), в котором + заменяется на -, а / на _, и часто опускается дополнение =. Этот вариант используется в JWT, data URI внутри URL и других контекстах, где стандартные символы Base64 конфликтовали бы с синтаксисом URL.
Ключевые различия
| Характеристика | URL-кодирование | Base64 |
|---|---|---|
| Стандарт | RFC 3986 | RFC 4648 |
| Назначение | Сделать URL безопасными | Представить двоичные данные как текст |
| Что кодирует | Только специальные/зарезервированные символы | Все входные байты |
| Формат вывода | Шестнадцатеричные последовательности %XX |
A-Z, a-z, 0-9, +, /, = |
| Увеличение размера | Переменное (растут только закодированные символы) | Всегда примерно на 33% больше |
| Обратимость | Да | Да |
| Читаемость для человека | Частичная (незарезервированные символы сохраняются) | Нет |
| URL-безопасность по умолчанию | Да (по замыслу) | Нет (содержит +, /, =) |
Когда что использовать
Используйте URL-кодирование, когда нужно включить специальные символы в URL, например значения параметров запроса, сегменты пути или идентификаторы фрагментов. URL-кодирование — правильный выбор для любой ситуации, где данные должны быть встроены в структуру URL.
Используйте Base64, когда нужно представить двоичные данные (изображения, файлы, зашифрованные полезные нагрузки) в виде текста, встроить двоичное содержимое в JSON или XML либо передать данные через текстовые каналы. Base64 также применяется в заголовках HTTP Basic Authentication и в JSON Web Tokens (JWT).
// URL-кодирование: встраивание поискового запроса в URL
const searchUrl = 'https://example.com/search?q=' +
encodeURIComponent('C++ & Java');
// "https://example.com/search?q=C%2B%2B%20%26%20Java"
// Base64: встраивание изображения в CSS или HTML
const imageData = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
// Base64: заголовок HTTP Basic Auth
const credentials = btoa('username:password');
const header = 'Authorization: Basic ' + credentials;
Можно ли их сочетать?
Да, а в некоторых случаях это необходимо. Если вам нужно передать данные, закодированные в Base64, как параметр URL, стандартный вывод Base64 может содержать символы +, / и =, которые имеют специальное значение в URL. У вас есть два варианта:
Вариант 1. Применить URL-кодирование к строке Base64 перед её размещением в URL. Тогда + превращается в %2B, / — в %2F, а = — в %3D.
Вариант 2. Использовать вариант Base64url (RFC 4648, раздел 5), в котором + заменяется на -, / на _, а дополнение убирается. Этот подход применяется в JWT и многих современных API.
// Вариант 1: URL-кодирование стандартного Base64
const base64 = btoa('binary data here'); // "YmluYXJ5IGRhdGEgaGVyZQ=="
const urlSafe = encodeURIComponent(base64);
// "YmluYXJ5IGRhdGEgaGVyZQ%3D%3D"
// Вариант 2: кодирование Base64url
function toBase64url(str) {
return btoa(str)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
toBase64url('binary data here');
// "YmluYXJ5IGRhdGEgaGVyZQ"