Base64 Кодирование/Декодирование в JavaScript: btoa(), atob() и Юникод
Кодирование и декодирование Base64 в JavaScript
JavaScript предоставляет несколько встроенных способов кодирования и декодирования строк Base64. Независимо от того, создаёте ли вы браузерное приложение или сервер на Node.js, понимание работы с Base64 необходимо для обработки бинарных данных в текстовых форматах, таких как JSON, HTML и URL.
Использование btoa() и atob() в браузере
Две основные функции для Base64 в браузерном JavaScript — это btoa() и atob(). Названия этих функций следуют устаревшей конвенции — btoa расшифровывается как «binary to ASCII» (из бинарного в ASCII), а atob — «ASCII to binary» (из ASCII в бинарный). Они поддерживаются во всех основных браузерах уже несколько десятилетий.
Кодирование с помощью btoa()
const originalString = 'Hello, world!';
const encoded = btoa(originalString);
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ==
Декодирование с помощью atob()
const base64String = 'SGVsbG8sIHdvcmxkIQ==';
const decoded = atob(base64String);
console.log(decoded);
// Output: Hello, world!
Обе функции работают со строками, содержащими только символы Latin-1 (каждый символ представлен одним байтом). Это важное ограничение, которое мы рассмотрим далее.
Обработка Юникода и символов не из ASCII
Распространённая ошибка: btoa() выбрасывает ошибку при передаче строк, содержащих символы за пределами диапазона Latin-1, такие как эмодзи, китайские иероглифы или буквы с диакритическими знаками.
btoa('Hello 你好');
// Error: The string to be encoded contains characters outside of the Latin-1 range.
Для кодирования строк Юникода необходимо сначала преобразовать строку в байты, а затем закодировать эти байты. Современный подход использует API TextEncoder и TextDecoder:
function unicodeToBase64(str) {
const bytes = new TextEncoder().encode(str);
const binaryString = String.fromCharCode(...bytes);
return btoa(binaryString);
}
function base64ToUnicode(base64) {
const binaryString = atob(base64);
const bytes = Uint8Array.from(binaryString, (c) => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
// Использование
const encoded = unicodeToBase64('Hello 你好 🚀');
console.log(encoded);
// Output: SGVsbG8g5L2g5aW9IPCfj4A=
const decoded = base64ToUnicode(encoded);
console.log(decoded);
// Output: Hello 你好 🚀
Более старый метод использует encodeURIComponent и decodeURIComponent, но подход с TextEncoder/TextDecoder более надёжен и является рекомендуемым современным решением.
Кодирование бинарных данных (ArrayBuffer)
При работе с файлами, изображениями или сырыми бинарными данными из API, таких как fetch или FileReader, вы обычно имеете дело с ArrayBuffer или Uint8Array. Вот как преобразовать их в Base64:
function arrayBufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
let binaryString = '';
for (let i = 0; i < bytes.length; i++) {
binaryString += String.fromCharCode(bytes[i]);
}
return btoa(binaryString);
}
function base64ToArrayBuffer(base64) {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
Преобразование файла в Base64 в браузере
Вот полный пример использования FileReader для преобразования выбранного пользователем файла в data URL Base64:
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(new Error('Failed to read file'));
reader.readAsDataURL(file);
});
}
// Использование с полем выбора файла
document.querySelector('input[type="file"]').addEventListener('change', async (e) => {
const file = e.target.files[0];
try {
const dataUrl = await fileToBase64(file);
console.log(dataUrl); // data:image/png;base64,iVBORw0KGgo...
} catch (err) {
console.error('Conversion failed:', err);
}
});
Использование Base64 в Node.js
Node.js предоставляет класс Buffer для операций с Base64, который более гибок, чем браузерные btoa/atob. Класс Buffer автоматически обрабатывает кодирование и декодирование, включая Юникод, и поддерживает множество форматов кодирования.
Базовое кодирование и декодирование
// Кодирование строки в Base64
const encoded = Buffer.from('Hello, world!').toString('base64');
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ==
// Декодирование строки Base64 обратно в текст
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded);
// Output: Hello, world!
Поддержка Юникода в Node.js
В отличие от btoa() в браузере, Buffer в Node.js беспрепятственно работает с Юникодом:
const encoded = Buffer.from('Hello 你好 🚀').toString('base64');
console.log(encoded);
// Output: SGVsbG8g5L2g5aW9IPCfj4A=
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded);
// Output: Hello 你好 🚀
Чтение файла и кодирование в Base64
const fs = require('fs');
// Чтение файла и кодирование в Base64
const buffer = fs.readFileSync('image.png');
const base64 = buffer.toString('base64');
const dataUrl = `data:image/png;base64,${base64}`;
Кодирование Base64url в Node.js
Node.js версии 15.7.0+ поддерживает нативное кодирование Base64url, которое заменяет + на - и / на _ и опускает дополнение:
const encoded = Buffer.from('Hello, world!').toString('base64url');
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ (без дополнения)
const decoded = Buffer.from(encoded, 'base64url').toString('utf-8');
console.log(decoded);
// Output: Hello, world!
Вопросы производительности
При работе с большими объёмами данных повторяющиеся операции с Base64 могут быть медленными. Вот несколько советов:
- Используйте
TextEncoder/TextDecoderвместо ручных преобразований для строк Юникода - В Node.js
Buffer.from()высоко оптимизирован — предпочитайте его ручным реализациям - Избегайте преобразования больших файлов в Base64 без необходимости (рассмотрите потоковую передачу)
- Для больших наборов данных рассмотрите использование
BlobиFileReaderв браузере, чтобы не блокировать основной поток
Попробуйте кодирование Base64 онлайн
Экспериментируйте с кодированием и декодированием прямо в браузере с помощью нашего бесплатного онлайн кодировщика и декодировщика Base64. Никакого программирования не требуется — просто вставьте текст или загрузите файл и мгновенно получите результат в Base64.