🔐
← Quay lại hướng dẫn

Mã hóa/giải mã Base64 trong JavaScript: btoa(), atob() và Unicode

· Thẻ: javascript, base64, btoa, atob, nodejs, encoding, web-development

Mã hóa và giải mã Base64 trong JavaScript

JavaScript cung cấp một số cách tích hợp để mã hóa và giải mã chuỗi Base64. Cho dù bạn đang xây dựng ứng dụng trình duyệt hay máy chủ Node.js, hiểu cách làm việc với Base64 là điều cần thiết để xử lý dữ liệu nhị phân trong các định dạng dựa trên văn bản như JSON, HTML và URL.

Sử dụng btoa() và atob() trong trình duyệt

Hai hàm cốt lõi cho Base64 trong JavaScript ở trình duyệt là btoa()atob(). Các tên hàm này tuân theo một quy ước đặt tên cũ — btoa là viết tắt của "binary to ASCII" (nhị phân sang ASCII) và atob là viết tắt của "ASCII to binary" (ASCII sang nhị phân). Chúng đã được hỗ trợ trong tất cả các trình duyệt lớn trong nhiều thập kỷ.

Mã hóa bằng btoa()

const originalString = 'Hello, world!';
const encoded = btoa(originalString);
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ==

Giải mã bằng atob()

const base64String = 'SGVsbG8sIHdvcmxkIQ==';
const decoded = atob(base64String);
console.log(decoded);
// Output: Hello, world!

Cả hai hàm đều hoạt động với chuỗi chỉ chứa ký tự Latin-1 (mỗi ký tự được biểu diễn bằng một byte). Đây là một hạn chế quan trọng mà chúng ta sẽ đề cập tiếp theo.

Xử lý ký tự Unicode và ký tự không phải Latin-1

Một lỗi thường gặp: btoa() ném lỗi khi được truyền chuỗi chứa ký tự ngoài phạm vi Latin-1, chẳng hạn như emoji, ký tự tiếng Trung hoặc chữ cái có dấu.

btoa('Hello 你好');
// Error: The string to be encoded contains characters outside of the Latin-1 range.

Để mã hóa chuỗi Unicode, bạn cần chuyển đổi chuỗi thành byte trước rồi mã hóa các byte đó. Cách tiếp cận hiện đại sử dụng các API TextEncoderTextDecoder:

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);
}

// Usage
const encoded = unicodeToBase64('Hello 你好 🚀');
console.log(encoded);
// Output: SGVsbG8g5L2g5aW9IPCfj4A=

const decoded = base64ToUnicode(encoded);
console.log(decoded);
// Output: Hello 你好 🚀

Một kỹ thuật cũ hơn sử dụng encodeURIComponentdecodeURIComponent, nhưng cách tiếp cận TextEncoder/TextDecoder mạnh mẽ hơn và là giải pháp hiện đại được khuyến nghị.

Mã hóa dữ liệu nhị phân (ArrayBuffer)

Khi làm việc với tệp, hình ảnh hoặc dữ liệu nhị phân thô từ các API như fetch hoặc FileReader, bạn thường có một ArrayBuffer hoặc Uint8Array. Đây là cách chuyển đổi nó sang 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;
}

Chuyển đổi tệp sang Base64 trong trình duyệt

Đây là một ví dụ hoàn chỉnh sử dụng FileReader để chuyển đổi tệp do người dùng chọn thành 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);
  });
}

// Usage with a file input
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);
  }
});

Sử dụng Base64 trong Node.js

Node.js cung cấp lớp Buffer cho các thao tác Base64, linh hoạt hơn btoa/atob của trình duyệt. Lớp Buffer xử lý mã hóa và giải mã tự động, bao gồm cả Unicode, và hỗ trợ nhiều định dạng mã hóa.

Mã hóa và giải mã cơ bản

// Encode a string to Base64
const encoded = Buffer.from('Hello, world!').toString('base64');
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ==

// Decode a Base64 string back to text
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded);
// Output: Hello, world!

Hỗ trợ Unicode trong Node.js

Không giống như btoa() trong trình duyệt, Buffer của Node.js xử lý Unicode một cách liền mạch:

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 你好 🚀

Đọc tệp và mã hóa thành Base64

const fs = require('fs');

// Read a file and encode it to Base64
const buffer = fs.readFileSync('image.png');
const base64 = buffer.toString('base64');
const dataUrl = `data:image/png;base64,${base64}`;

Mã hóa Base64url trong Node.js

Node.js 15.7.0+ hỗ trợ mã hóa Base64url gốc, thay + bằng -/ bằng _ đồng thời bỏ qua phần đệm:

const encoded = Buffer.from('Hello, world!').toString('base64url');
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ (no padding)

const decoded = Buffer.from(encoded, 'base64url').toString('utf-8');
console.log(decoded);
// Output: Hello, world!

Cân nhắc về hiệu suất

Đối với dữ liệu lớn, các thao tác Base64 lặp đi lặp lại có thể chậm. Dưới đây là một số mẹo:

  • Sử dụng TextEncoder/TextDecoder thay vì chuyển đổi thủ công cho chuỗi Unicode
  • Trong Node.js, Buffer.from() được tối ưu hóa cao — hãy ưu tiên nó hơn các triển khai thủ công
  • Tránh chuyển đổi các tệp lớn sang Base64 trừ khi cần thiết (cân nhắc phát trực tuyến)
  • Đối với các tập dữ liệu lớn, hãy cân nhắc sử dụng BlobFileReader trong trình duyệt để tránh chặn luồng chính

Thử mã hóa Base64 trực tuyến

Hãy thử nghiệm mã hóa và giải mã ngay trong trình duyệt của bạn bằng trình mã hóa và giải mã Base64 trực tuyến miễn phí của chúng tôi. Không cần viết mã — chỉ cần dán văn bản hoặc tải lên tệp và nhận kết quả Base64 ngay lập tức.