为什么 window.btoa 不能处理 Javascript 中的 – ” 字符?

chr*_*o25 5 javascript

所以我将字符串转换为 BASE64,如下面的代码所示......

\n
var str = "Hello World";\nvar enc = window.btoa(str);\n
Run Code Online (Sandbox Code Playgroud)\n

这产生SGVsbG8gV29ybGQ=. 但是,如果我添加这些字符(\xe2\x80\x93 \xe2\x80\x9d例如下面所示的代码),则不会发生转换。这背后的原因是什么?太感谢了。

\n
var str = "Hello \xe2\x80\x93 World\xe2\x80\x9d";\nvar enc = window.btoa(str);\n
Run Code Online (Sandbox Code Playgroud)\n

Mik*_*ans 10

btoa是一个奇特的函数,因为它需要一个“二进制字符串”,即它是一种String数据类型,但每个“字母”并不代表一个字母而是一个字节。因此,您不能有任何 Unicode 代码点高于 0xFF(字符代码 255)的“字母”,例如破折号和“花式”引号符号所使用的“字母”。

\n

您必须首先对数据进行 uri 编码,以确保其安全:

\n
> var str = `Hello \xe2\x80\x93 World`;\n> window.btoa(encodeURIComponent(str));\n"SGVsbG8lMjAlRTIlODAlOTMlMjBXb3JsZA=="\n
Run Code Online (Sandbox Code Playgroud)\n

然后记得在解压时再次解码:

\n
> var base64= "SGVsbG8lMjAlRTIlODAlOTMlMjBXb3JsZA==";\n> decodeURIComponent(window.atob(base64));\n"Hello \xe2\x80\x93 World"\n
Run Code Online (Sandbox Code Playgroud)\n

或者依赖于自动应用 URI 解码的目标,例如href属性 ( a,link等)。

\n

但是,如果您的目标不这样做(您自己的代码或、等src上的属性),那么您需要将字符串转换为符合单字节打包的新字符串。MDN上明确指出了这一点,他们的解决方案是:imgscript

\n
function base64(data) {\n  const bytes = new TextEncoder().encode(data);\n  const binString = String.fromCodePoint(...bytes);\n  return btoa(binString);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

使用等效解码器:

\n
function decode64(base64) {\n  const binString = atob(base64);\n  const bytes = Uint8Array.from(binString, (m) => m.codePointAt(0));\n  return new TextDecoder().decode(bytes);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

decode64如果您想在自己的代码中解压内容,则需要使用,但该base64函数将生成一个转换后的字符串,该字符串在放入 data-url 时将起作用(例如data:text/javascript;base64,${base64text});

\n

  • @Kaiido:这个确切的输入没有base64编码,因为base64不是在Unicode字符串上定义的,而是在字节流上定义的。只有特定编码中的字符串表示形式才具有 Base64 编码,并且编码的选择是任意的。可能是UTF-8,也可能是URL编码的UTF-8;唯一重要的是端点同意编码/解码步骤。 (2认同)