JavaScript使用atob解码含希伯来语的Base64字符串乱码求助
解决JavaScript atob解码含希伯来语Base64字符串乱码问题
问题描述
尝试用window.atob()解码包含希伯来语的HTML表格Base64字符串,解码后希伯来语显示为乱码。相关Base64字符串及代码如下:
待解码的Base64字符串
PHRhYmxlIGRpcj0ncnRsJyBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+DQo8dGhlYWQ+DQo8dGggc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPtee16En15M8L3RoPjx0aCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+16rXkNeo15nXmiDXlNeq15fXnNeUPC90aD48dGggc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPteq15DXqNeZ15og16HXmdeV1508L3RoPjx0aCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+16nXoteV16og16LXkdeV15PXlDwvdGg+PC90aGVhZD4NCjx0cj48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPjE8L3RkPjx0ZCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+MjMtMDktMjAyMjwvdGQ+PHRkIHN0eWxlPSdib3JkZXI6IDFweCBzb2xpZCBibGFjazsgIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7Jz4yNC0wOS0yMDIyPC90ZD48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPteR16nXoteV16og15TXoteR15XXk9eUINeU16jXkteZ15zXldeqPC90ZD48L3RyPjx0cj48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPjI8L3RkPjx0ZCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+MjUtMDktMjAyMjwvdGQ+PHRkIHN0eWxlPSdib3JkZXI6IDFweCBzb2xpZCBibGFjazsgIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7Jz4yNy0wOS0yMDIyPC90ZD48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPtep16LXldeqINeU16LXkdeV15PXlCDXlNeo15LXmdec15XXqjwvdGQ+PC90cj4NCjwvdGFibGU+
原使用代码
<p id="table"></p> <script charset="utf-8"> let decoded = window.atob("PHRhYmxlIGRpcj0ncnRsJyBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+DQo8dGhlYWQ+DQo8dGggc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPtee16En15M8L3RoPjx0aCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+16rXkNeo15nXmiDXlNeq15fXnNeUPC90aD48dGggc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPteq15DXqNeZ15og16HXmdeV1508L3RoPjx0aCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+16nXoteV16og16LXkdeV15PXlDwvdGg+PC90aGVhZD4NCjx0cj48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPjE8L3RkPjx0ZCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+MjMtMDktMjAyMjwvdGQ+PHRkIHN0eWxlPSdib3JkZXI6IDFweCBzb2xpZCBibGFjazsgIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7Jz4yNC0wOS0yMDIyPC90ZD48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPteR16nXoteV16og15TXoteR15XXk9eUINeU16jXkteZ15zXldeqPC90ZD48L3RyPjx0cj48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPjI8L3RkPjx0ZCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+MjUtMDktMjAyMjwvdGQ+PHRkIHN0eWxlPSdib3JkZXI6IDFweCBzb2xpZCBibGFjazsgIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7Jz4yNy0wOS0yMDIyPC90ZD48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPtep16LXldeqINeU16LXkdeV15PXlCDXlNeo15LXmdec15XXqjwvdGQ+PC90cj4NCjwvdGFibGU+"); document.getElementById("table").innerHTML = decoded; </script>
问题原因
window.atob()仅能正确解码基于ASCII编码的Base64字符串。希伯来语属于UTF-8字符,每个字符占用多个字节,直接用atob()解码时,会把UTF-8的多字节序列拆成单个ASCII字符处理,导致字符编码错乱,显示为乱码。
解决方案
改用Uint8Array和TextDecoder处理UTF-8编码的Base64字符串,步骤如下:
- 用
atob()把Base64转成二进制字符串 - 将二进制字符串的每个字符转成对应字节,存入
Uint8Array - 用
TextDecoder以UTF-8格式解码Uint8Array得到正确字符串
修改后的代码:
<p id="table"></p> <script charset="utf-8"> const base64Str = "PHRhYmxlIGRpcj0ncnRsJyBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+DQo8dGhlYWQ+DQo8dGggc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPtee16En15M8L3RoPjx0aCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+16rXkNeo15nXmiDXlNeq15fXnNeUPC90aD48dGggc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPteq15DXqNeZ15og16HXmdeV1508L3RoPjx0aCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+16nXoteV16og16LXkdeV15PXlDwvdGg+PC90aGVhZD4NCjx0cj48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPjE8L3RkPjx0ZCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+MjMtMDktMjAyMjwvdGQ+PHRkIHN0eWxlPSdib3JkZXI6IDFweCBzb2xpZCBibGFjazsgIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7Jz4yNC0wOS0yMDIyPC90ZD48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPteR16nXoteV16og15TXoteR15XXk9eUINeU16jXkteZ15zXldeqPC90ZD48L3RyPjx0cj48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPjI8L3RkPjx0ZCBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgYmxhY2s7ICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOyc+MjUtMDktMjAyMjwvdGQ+PHRkIHN0eWxlPSdib3JkZXI6IDFweCBzb2xpZCBibGFjazsgIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7Jz4yNy0wOS0yMDIyPC90ZD48dGQgc3R5bGU9J2JvcmRlcjogMXB4IHNvbGlkIGJsYWNrOyAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsnPtep16LXldeqINeU16LXkdeV15PXlCDXlNeo15LXmdec15XXqjwvdGQ+PC90cj4NCjwvdGFibGU+"; // 步骤1:解码Base64为二进制字符串 const binaryStr = window.atob(base64Str); // 步骤2:将二进制字符串转为Uint8Array const uint8Array = new Uint8Array(binaryStr.length); for (let i = 0; i < binaryStr.length; i++) { uint8Array[i] = binaryStr.charCodeAt(i); } // 步骤3:用UTF-8解码Uint8Array const decoder = new TextDecoder('utf-8'); const decoded = decoder.decode(uint8Array); document.getElementById("table").innerHTML = decoded; </script>
补充说明
TextDecoder是现代浏览器原生支持的API,无需额外引入库,能准确处理UTF-8等多字节编码- 如果需要兼容旧版浏览器,可以用
unescape(encodeURIComponent(atob(base64Str)))替代,但该方法已不推荐,优先使用TextDecoder方案
内容的提问来源于stack exchange,提问作者Druz
相关产品推荐
相关产品推荐

