Tôi thấy rằng mặc dù các miếng chêm từ các câu trả lời ở trên đã hoạt động, nhưng chúng không khớp với hành vi triển khai của trình duyệt máy tính để bàn btoa()và atob():
const btoa = function(str){ return Buffer.from(str).toString('base64'); }
// returns "4pyT", yet in desktop Chrome would throw an error.
btoa('✓');
// returns "fsO1w6bCvA==", yet in desktop Chrome would return "fvXmvA=="
btoa(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));
Hóa ra, Buffer thể hiện đại diện / giải thích các chuỗi được mã hóa theo UTF-8 theo mặc định . Ngược lại, trong Chrome dành cho máy tính để bàn, bạn thậm chí không thể nhập một chuỗi có chứa các ký tự bên ngoài phạm vi latin1 btoa(), vì nó sẽ đưa ra một ngoại lệ:Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
Do đó, bạn cần đặt rõ ràng loại mã hóa thành latin1để shim Node.js của bạn khớp với loại mã hóa của Chrome trên máy tính để bàn:
const btoaLatin1 = function(str) { return Buffer.from(str, 'latin1').toString('base64'); }
const atobLatin1 = function(b64Encoded) {return Buffer.from(b64Encoded, 'base64').toString('latin1');}
const btoaUTF8 = function(str) { return Buffer.from(str, 'utf8').toString('base64'); }
const atobUTF8 = function(b64Encoded) {return Buffer.from(b64Encoded, 'base64').toString('utf8');}
btoaLatin1('✓'); // returns "Ew==" (would be preferable for it to throw error because this is undecodable)
atobLatin1(btoa('✓')); // returns "\u0019" (END OF MEDIUM)
btoaUTF8('✓'); // returns "4pyT"
atobUTF8(btoa('✓')); // returns "✓"
// returns "fvXmvA==", just like desktop Chrome
btoaLatin1(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));
// returns "fsO1w6bCvA=="
btoaUTF8(String.fromCharCode.apply(null, new Uint8Array([0x7e, 0xf5, 0xe6, 0xbc])));