[程式碼]
6 分鐘閱讀
[程式碼] Base64 在 JavaScript 中的應用
Base64 編碼與解碼的實用 JavaScript 範例,使用現代瀏覽器 API。
2025年1月
|
development
// 基本編碼與解碼
JavaScript 提供了內建的 Base64 操作函數。btoa() 和 atob() 函數處理基本的編碼和解碼:
這些函數適用於 ASCII 文字,但處理 Unicode 字元時需要特殊處理。
// 基本 Base64 編碼
const text = 'Hello World';
const encoded = btoa(text);
console.log(encoded); // SGVsbG8gV29ybGQ=
// 基本 Base64 解碼
const decoded = atob(encoded);
console.log(decoded); // Hello World
// 檢查字串是否為有效的 Base64
function isValidBase64(str) {
try {
return btoa(atob(str)) === str;
} catch (err) {
return false;
}
}
// UNICODE 支援
對於 Unicode 字串,我們需要先轉換為 UTF-8 字節。現代瀏覽器提供 TextEncoder 和 TextDecoder API:
這種方法正確處理表情符號、國際字元和其他 Unicode 內容。
// Unicode 安全的 Base64 編碼
function encodeBase64(str) {
const encoder = new TextEncoder();
const bytes = encoder.encode(str);
const binary = String.fromCharCode(...bytes);
return btoa(binary);
}
// Unicode 安全的 Base64 解碼
function decodeBase64(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
const decoder = new TextDecoder();
return decoder.decode(bytes);
}
// 表情符號範例
const emoji = 'Hello 👋 World 🌍';
const encoded = encodeBase64(emoji);
const decoded = decodeBase64(encoded);
console.log(decoded); // Hello 👋 World 🌍
// 檔案處理
將檔案轉換為 Base64 常用於上傳和資料 URI。在客戶端使用 FileReader API 進行檔案處理:
這會創建可直接嵌入 HTML 或發送到 API 的資料 URI。
// 將檔案轉換為 Base64 資料 URI
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
reader.readAsDataURL(file);
});
}
// 與檔案輸入一起使用
document.getElementById('fileInput').addEventListener('change', async (e) => {
const file = e.target.files[0];
if (file) {
try {
const base64 = await fileToBase64(file);
console.log(base64);
// 結果:data:image/png;base64,iVBORw0KGgoAAAA...
} catch (error) {
console.error('錯誤:', error);
}
}
});
// URL 安全的 BASE64
標準 Base64 使用 + 和 / 字元,需要 URL 編碼。URL 安全的 Base64 用 - 和 _ 替換這些字元:
這對於令牌、ID 和其他透過 URL 傳輸的資料至關重要。
// 轉換為 URL 安全的 Base64
function toUrlSafeBase64(base64) {
return base64
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// 從 URL 安全的 Base64 轉換
function fromUrlSafeBase64(urlSafeBase64) {
let base64 = urlSafeBase64
.replace(/-/g, '+')
.replace(/_/g, '/');
// 如需要則添加填充
const padding = 4 - (base64.length % 4);
if (padding !== 4) {
base64 += '='.repeat(padding);
}
return base64;
}
// 範例
const text = 'URL-safe encoding test';
const encoded = btoa(text);
const urlSafe = toUrlSafeBase64(encoded);
console.log(urlSafe); // VVJMLXNhZmUgZW5jb2RpbmcgdGVzdA
// 串流大資料
對於大型檔案或資料串流,分塊處理以避免記憶體問題:
這種方法防止瀏覽器凍結並有效處理大型資料集。
// 基於串流的 Base64 編碼
class Base64Encoder {
constructor() {
this.buffer = '';
}
encode(chunk) {
this.buffer += chunk;
const completeBytes = Math.floor(this.buffer.length / 3) * 3;
const toEncode = this.buffer.slice(0, completeBytes);
this.buffer = this.buffer.slice(completeBytes);
return btoa(toEncode);
}
flush() {
if (this.buffer.length > 0) {
const result = btoa(this.buffer);
this.buffer = '';
return result;
}
return '';
}
}
// 使用方法
const encoder = new Base64Encoder();
let result = '';
result += encoder.encode('First chunk');
result += encoder.encode(' Second chunk');
result += encoder.flush();
console.log(result);
// 錯誤處理
總是為 Base64 操作實施適當的錯誤處理:
穩健的錯誤處理防止應用程式崩潰並提供更好的使用者體驗。
// 具有錯誤處理的安全 Base64 操作
function safeEncode(input) {
try {
if (typeof input !== 'string') {
throw new Error('輸入必須是字串');
}
return btoa(input);
} catch (error) {
console.error('編碼錯誤:', error.message);
return null;
}
}
function safeDecode(base64) {
try {
// 驗證 Base64 格式
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(base64)) {
throw new Error('無效的 Base64 格式');
}
return atob(base64);
} catch (error) {
console.error('解碼錯誤:', error.message);
return null;
}
}
// 使用方法
const encoded = safeEncode('Hello World');
const decoded = safeDecode(encoded);
if (encoded && decoded) {
console.log('成功:', decoded);
}