JavaScript 的 atob() 函数旨在解码 Base64 编码的字符串。用户在解码 UTF-8 编码字符串时可能会遇到问题,导致生成 ASCII 编码字符而不是正确的 UTF-8 表示形式。
Base64 需要二进制数据作为输入,JavaScript将字符占据一个字节的字符串视为二进制数据。然而,在 UTF-8 编码的字符串中,字符占用超过 1 个字节时,会在编码过程中触发异常。
建议的修复方法是对二进制字符串进行编码和解码:
将 UTF-8 编码为二进制
function toBinary(string) { const codeUnits = new Uint16Array(string.length); for (let i = 0; i将二进制解码为 UTF-8
function fromBinary(encoded) { const binary = atob(encoded); const bytes = new Uint8Array(binary.length); for (let i = 0; i此解决方案将原始 UTF-8 字符串转换为二进制表示形式,保留 UTF-16 编码(JavaScript 中的本机表示形式)。
解决方案 2:ASCII Base64 互操作性
专注于 UTF-8 互操作性的替代解决方案是维护纯文本 base64 字符串:
编码UTF-8 转 Base64
function b64EncodeUnicode(str) { return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) { return String.fromCharCode('0x' p1); })); }解码 Base64 为 UTF-8
function b64DecodeUnicode(str) { return decodeURIComponent(atob(str).split('').map(function(c) { return '%' ('00' c.charCodeAt(0).toString(16)).slice(-2); }).join('')); }此解决方案可有效处理 UTF-8 编码的字符串,而不改变其表示形式。
TypeScript 支持
// Encoding UTF-8 ⇢ base64 function b64EncodeUnicode(str) { return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) { return String.fromCharCode(parseInt(p1, 16)) })) } // Decoding base64 ⇢ UTF-8 function b64DecodeUnicode(str) { return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) { return '%' ('00' c.charCodeAt(0).toString(16)).slice(-2) }).join('')) }历史解决方案(已弃用)
function utf8_to_b64( str ) { return window.btoa(unescape(encodeURIComponent( str ))); } function b64_to_utf8( str ) { return decodeURIComponent(escape(window.atob( str ))); }虽然仍然有效,但这种方法现在在现代浏览器中已被弃用。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3