🔐
← Назад к руководствам

Base64 Кодирование/Декодирование в JavaScript: btoa(), atob() и Юникод

· Теги: javascript, base64, btoa, atob, nodejs, encoding, web-development

Кодирование и декодирование 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.