🔐
← กลับไปคู่มือ

การเข้ารหัส/ถอดรหัส Base64 ใน JavaScript: btoa(), atob() และ Unicode

· แท็ก: 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" และ atob ย่อมาจาก "ASCII to binary" ฟังก์ชันเหล่านี้ได้รับการสนับสนุนในเบราว์เซอร์หลักทั้งหมดมานานหลายทศวรรษ

การเข้ารหัสด้วย 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 (แต่ละอักขระแทนด้วยไบต์เดียว) นี่เป็นข้อจำกัดสำคัญที่เราจะกล่าวถึงต่อไป

การจัดการ Unicode และอักขระที่ไม่ใช่ ASCII

ปัญหาที่พบบ่อย: btoa() จะเกิดข้อผิดพลาดเมื่อได้รับสตริงที่มีอักขระนอกช่วง Latin-1 เช่น อีโมจิ อักขระภาษาจีน หรืออักษรที่มีเครื่องหมายเน้นเสียง

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

ในการเข้ารหัสสตริง Unicode คุณต้องแปลงสตริงเป็นไบต์ก่อน แล้วจึงเข้ารหัสไบต์เหล่านั้น วิธีการสมัยใหม่ใช้ TextEncoder และ TextDecoder API:

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

เทคนิคที่เก่ากว่าใช้ 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 เพื่อแปลงไฟล์ที่ผู้ใช้เลือกเป็น Base64 data URL:

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

การใช้ Base64 ใน Node.js

Node.js มีคลาส Buffer สำหรับการดำเนินการ Base64 ซึ่งยืดหยุ่นกว่า btoa/atob ของเบราว์เซอร์ คลาส Buffer จัดการการเข้ารหัสและถอดรหัสโดยอัตโนมัติ รวมถึง Unicode และรองรับรูปแบบการเข้ารหัสหลายรูปแบบ

การเข้ารหัสและถอดรหัสพื้นฐาน

// 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!

การรองรับ Unicode ใน Node.js

ต่างจาก btoa() ในเบราว์เซอร์ Buffer ของ Node.js จัดการ Unicode ได้อย่างราบรื่น:

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

// 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}`;

การเข้ารหัส Base64url ใน Node.js

Node.js 15.7.0+ รองรับการเข้ารหัส Base64url โดยตรง ซึ่งแทนที่ + ด้วย - และ / ด้วย _ และละ padding:

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!

ข้อควรพิจารณาด้านประสิทธิภาพ

สำหรับข้อมูลขนาดใหญ่ การดำเนินการ Base64 ซ้ำๆ อาจช้าได้ นี่คือเคล็ดลับบางประการ:

  • ใช้ TextEncoder/TextDecoder แทนการแปลงด้วยตนเองสำหรับสตริง Unicode
  • ใน Node.js Buffer.from() ถูกปรับให้เหมาะสมอย่างมาก — ควรใช้แทนการเขียนฟังก์ชันเอง
  • หลีกเลี่ยงการแปลงไฟล์ขนาดใหญ่เป็น Base64 เว้นแต่จำเป็น (พิจารณาใช้ streaming)
  • สำหรับชุดข้อมูลขนาดใหญ่ พิจารณาใช้ Blob และ FileReader ในเบราว์เซอร์เพื่อหลีกเลี่ยงการบล็อก main thread

ลองใช้การเข้ารหัส Base64 ออนไลน์

ทดลองการเข้ารหัสและถอดรหัสในเบราว์เซอร์ของคุณโดยใช้ เครื่องมือเข้ารหัสและถอดรหัส Base64 ออนไลน์ฟรี ไม่ต้องเขียนโค้ด — เพียงวางข้อความหรืออัปโหลดไฟล์และรับผลลัพธ์ Base64 ทันที