【发布时间】:2017-07-15 03:52:08
【问题描述】:
我有一个字节数组,我想将其编码为字符串以传递给浏览器中的btoa。这些字节使用完整的 0-255 范围。起初我遇到了btoa 的错误,但事实证明这是javascript 的 Array.prototype.join 的错误(或至少是相当意外的行为)。为了说明问题,我将从一些 base64 编码的数据开始:
gACJNqQ0cg==
这可以解码为一个字节数组,如下所示:
atob('gACJNqQ0cg==').split('').map(c => c.charCodeAt(0))
> [128, 0, 137, 54, 164, 52, 114]
现在,您希望能够反转操作并取回原始字符串:
btoa([128, 0, 137, 54, 164, 52, 114].map(String.fromCharCode).join(''))
但是,你会得到一个更大的字符串:
gAAAAAEAiQIANgMApAQANAUAcgYA
经过进一步调查,在加入使用 String.fromCharCode 创建的任何字符串时会出现问题:
'Hi'.split('').join('').length
> 2
'Hi'.split('').map(c => c.charCodeAt(0))
> [72, 105]
[72, 105].map(String.fromCharCode).join('').length
> 6
//what?
在我尝试过的所有地方都能看到这种行为:Chrome (60)、Firefox (53) 和 Node (6.9.4)。在浏览器中,您没有简单的替代方案,例如 node 的
new Buffer(array, 'binary').toString('base64') 来解决这个问题。如何安全地从字节值数组创建字符串,并将其传递给btoa?
【问题讨论】:
-
String.fromCharCode被多个参数调用(因为map以这种方式工作),这就是你得到不同结果的原因。
标签: javascript character-encoding fromcharcode