การเข้ารหัส/ถอดรหัส Base64 ใน JavaScript: btoa(), atob() และ Unicode
การเข้ารหัสและถอดรหัส 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 ทันที