Window: btoa() 方法
Window 接口的 btoa() 方法从一个二进制字符串(即,字符串中的每个字符都被视为二进制数据的一个字节)创建一个 Base64 编码的 ASCII 字符串。
你可以使用此方法编码可能导致通信问题的数据,传输数据,然后使用 Window.atob() 方法再次解码数据。例如,你可以编码控制字符,例如 ASCII 值 0 到 31。
如果你的数据在一个 Uint8Array 对象中,也请考虑使用 Uint8Array.prototype.toBase64() 方法,以避免创建包含原始字节的字符串。
语法
btoa(stringToEncode)
参数
stringToEncode-
要编码的二进制字符串。JavaScript 中的字符串编码为 UTF-16,因此这意味着每个字符的代码点必须小于 256,表示一个字节的数据。
返回值
一个包含 stringToEncode 的 Base64 表示的 ASCII 字符串。
异常
InvalidCharacterErrorDOMException-
字符串中包含的字符不适合单个字节。有关更多详细信息,请参阅下面的“Unicode 字符串”。
示例
const encodedData = window.btoa("Hello, world"); // encode a string
const decodedData = window.atob(encodedData); // decode the string
Unicode 字符串
Base64,顾名思义,需要二进制数据作为输入。就 JavaScript 字符串而言,这意味着字符串中每个字符的代码点只占用一个字节。因此,如果你将一个包含占用多个字节的字符的字符串传递给 btoa(),你将收到一个错误,因为这不被视为二进制数据。
const ok = "a";
console.log(ok.codePointAt(0).toString(16)); // 61: occupies < 1 byte
const notOK = "✓";
console.log(notOK.codePointAt(0).toString(16)); // 2713: occupies > 1 byte
console.log(window.btoa(ok)); // YQ==
console.log(window.btoa(notOK)); // error
由于 btoa 将其输入字符串的代码点解释为字节值,因此如果字符的代码点超过 0xff,在字符串上调用 btoa 将导致“字符超出范围”异常。对于需要编码任意 Unicode 文本的用例,需要先将字符串转换为其组成字节的 UTF-8,然后编码这些字节。
最简单的解决方案是使用 TextEncoder 和 TextDecoder 在 UTF-8 和字符串的单字节表示之间进行转换。
function base64ToBytes(base64) {
const binString = atob(base64);
return Uint8Array.from(binString, (m) => m.codePointAt(0));
}
function bytesToBase64(bytes) {
const binString = Array.from(bytes, (byte) =>
String.fromCodePoint(byte),
).join("");
return btoa(binString);
}
// Usage
bytesToBase64(new TextEncoder().encode("a Ā 𐀀 文 🦄")); // "YSDEgCDwkICAIOaWhyDwn6aE"
new TextDecoder().decode(base64ToBytes("YSDEgCDwkICAIOaWhyDwn6aE")); // "a Ā 𐀀 文 🦄"
转换任意二进制数据
上一节中的 bytesToBase64 和 base64ToBytes 函数可以直接用于在 Base64 字符串和 Uint8Array 之间进行转换。
为了获得更好的性能,通过 FileReader 和 fetch API,可以在 Web 平台中本地实现 Base64 数据 URL 之间的异步转换。
async function bytesToBase64DataUrl(bytes, type = "application/octet-stream") {
return await new Promise((resolve, reject) => {
const reader = Object.assign(new FileReader(), {
onload: () => resolve(reader.result),
onerror: () => reject(reader.error),
});
reader.readAsDataURL(new File([bytes], "", { type }));
});
}
async function dataUrlToBytes(dataUrl) {
const res = await fetch(dataUrl);
return new Uint8Array(await res.arrayBuffer());
}
// Usage
await bytesToBase64DataUrl(new Uint8Array([0, 1, 2])); // "data:application/octet-stream;base64,AAEC"
await dataUrlToBytes("data:application/octet-stream;base64,AAEC"); // Uint8Array [0, 1, 2]
注意:对于支持环境,也请考虑原生的 Uint8Array.fromBase64()、Uint8Array.prototype.toBase64() 和 Uint8Array.prototype.setFromBase64() 方法。
规范
| 规范 |
|---|
| HTML # dom-btoa-dev |
浏览器兼容性
加载中…
另见
btoa的 polyfill 在core-js中可用。dataURLWorkerGlobalScope.btoa():相同的方法,但在 Worker 作用域中。Window.atob()Uint8Array.prototype.toBase64()- Base64