Base64URL против стандартного Base64: алфавит, заполнение и синтаксический анализ URL

Распознавайте тире и подчеркивание, понимайте необязательные дополнения и избегайте искажений при добавлении плюса к пробелу в параметрах запроса URL.

Base64URL изменяет два символа алфавита: стандартный плюс Base64 становится тире, а косая черта становится подчеркиванием. Закодированная информация не изменяется. Этот вариант помогает, когда окружающий протокол придает особое значение плюсу или косой черте, но не исключает значение из каждого URL или правила приложения.

Используйте вектор, который показывает разницу

Байты FB FF кодируются как +/8= в стандарте Base64 и -_8= в Base64URL. Такой тест, как Hello, создает только общие символы алфавита, поэтому он не может определить, работает ли безопасное преобразование URL.

const standard = btoa(String.fromCharCode(251, 255));
const urlSafe = standard.replace(/\+/g, '-').replace(/\//g, '_');
console.log(standard); // +/8=
console.log(urlSafe); // -_8=

Заполнение - отдельное соглашение

Многие форматы токенов опускают завершающие знаки равенства, а другие системы сохраняют их. Изменение алфавита и удаление дополнения — независимые решения. Если длина строки без дополнения при делении на 4 даёт остаток 2, нужно добавить два знака равенства; если остаток равен 3, нужен один знак. Остаток 1 нельзя исправить одним лишь добавлением знаков, поскольку одного шестибитного символа недостаточно для представления полного байта.

При проверке также проверьте неиспользуемые биты в последнем символе. Декодер, который их игнорирует, может принять несколько строк для одной и той же последовательности байтов. Эта неоднозначность может иметь значение, когда приложение сравнивает закодированные строки вместо декодированных байтов. Канонический производитель должен выдать одно согласованное представление.

Не путайте синтаксический анализ запроса с декодированием Base64.

Анализ запросов в стиле формы интерпретирует литерал плюс как пробел. Поэтому стандартное значение Base64, вставленное в запрос без экранирования, может быть повреждено до того, как декодер его увидит. Создайте запрос с помощью URLSearchParamsили используйте вариант Base64URL, если это указано в протоколе приема.

const query = new URLSearchParams({ payload: '+/8=' });
console.log(query.toString()); // payload=%2B%2F8%3D
console.log(query.get('payload')); // +/8=

Не заменяйте каждый пробел автоматически плюсом: пробел может означать подлинное форматирование или свидетельство другой ошибки. Сохраните источник, определите транспортный уровень, который его изменил, и примените целенаправленную коррекцию. Для сегментов JWT используйте правила формата токена Base64URL, а не изобретайте общую политику восстановления.

Стандартные и URL-безопасные алфавиты описаны в RFC 4648. Ваша интеграция по-прежнему требует явного выбора заполнения, допуска пробелов и максимальной длины.