Uint8Array.prototype.setFromBase64()
Uint8Array 实例的 setFromBase64() 方法使用来自 base64 编码字符串的字节填充此 Uint8Array 对象,并返回一个指示读取和写入了多少字节的对象。
此方法最适合填充预先分配的数组缓冲区。如果您只想从 base64 编码字符串创建新的 Uint8Array 对象,请改用静态方法 Uint8Array.fromBase64()。
语法
setFromBase64(string)
setFromBase64(string, options)
参数
string-
一个 base64 字符串,用于编码要写入
Uint8Array的字节。它与Uint8Array.fromBase64()的string参数具有相同的要求。请注意,字符串仅读取到数组被填满为止,因此该点之后的所有无效 base64 语法都会被忽略。 options可选-
一个自定义 base64 字符串解释过程的对象。它与
Uint8Array.fromBase64()的options参数具有相同的要求。
返回值
包含以下属性的对象:
read-
从输入字符串中读取的 base64 字符数。如果解码的数据适合数组,则这是输入字符串的长度(包括填充);否则,它是适合数组的最后一个完整 4 字符块的长度。块永远不会被拆分(因为剩余位不能在不完全重新编码的情况下部分“放回” base64);如果下一个块无法放入数组的剩余部分,它将完全未被读取,导致数组的最后一两个字节未被写入。
written-
写入
Uint8Array的字节数。永远不会大于此Uint8Array的byteLength。
异常
SyntaxError-
如果输入字符串包含指定字母表之外的字符,或者最后一个块不满足
lastChunkHandling选项,则会抛出此错误。 TypeError-
在以下情况之一中抛出
- 输入字符串不是字符串。
options对象不是对象或undefined。- 选项不是预期的值或
undefined。
示例
解码 base64 字符串
此示例使用默认的 alphabet 和 lastChunkHandling 选项将 base64 字符串解码到现有的 Uint8Array 中。
const uint8Array = new Uint8Array(16);
const result = uint8Array.setFromBase64("PGI+ TURO PC9i Pg==");
console.log(result); // { read: 19, written: 10 }
console.log(uint8Array);
// Uint8Array(16) [60, 98, 62, 77, 68, 78, 60, 47, 98, 62, 0, 0, 0, 0, 0, 0]
将大字符串解码到小数组中
如果字符串包含的数据超过了数组的容量,则方法只会写入数组能容纳的字节数,而不会丢弃任何位。
const uint8Array = new Uint8Array(8);
const result = uint8Array.setFromBase64("PGI+ TURO PC9i Pg==");
console.log(result); // { read: 9, written: 6 }
console.log(uint8Array);
// Uint8Array(8) [60, 98, 62, 77, 68, 78, 0, 0]
请注意,数组的最后两个字节未被写入。为了解码这两个字节,我们需要读取至少三个额外的 base64 字符,这代表 18 位。这无法放入数组剩余的两个字节中,因此我们只能写入 2 个块,即 6 个字节。
在特定偏移量设置数据
setFromBase64() 方法始终从 Uint8Array 的开头开始写入。如果您想写入数组的中间部分,可以改用 TypedArray.prototype.subarray() 进行写入。
const uint8Array = new Uint8Array(16);
// Start writing at offset 2
const result = uint8Array.subarray(2).setFromBase64("PGI+ TURO PC9i Pg==");
console.log(result); // { read: 19, written: 10 }
console.log(uint8Array);
// Uint8Array(16) [0, 0, 60, 98, 62, 77, 68, 78, 60, 47, 98, 62, 0, 0, 0, 0]
流式解码
此示例改编自 原始提案。它使用 stream 选项模仿了 TextDecoder API。请注意使用 lastChunkHandling: "stop-before-partial" 来处理不完整的块。
class Base64Decoder {
#extra = "";
decode(chunk = "", options = {}) {
const opts = { ...options };
// match TextEncoder API
if (opts.stream) {
opts.lastChunkHandling = "stop-before-partial";
}
chunk = this.#extra + chunk;
this.#extra = "";
// For simplicity, allocate new memory every time
// the calculation below is guaranteed to be enough,
// but may be too much if there is whitespace
// if you're really concerned about memory, a TextDecoder style API is a bad choice
let buffer = new Uint8Array(Math.ceil((chunk.length * 3) / 4));
const { read, written } = buffer.setFromBase64(chunk, opts);
buffer = buffer.subarray(0, written);
this.#extra = chunk.slice(read);
return buffer;
}
}
const decoder = new Base64Decoder();
console.log(decoder.decode("SG Vsb ", { stream: true }));
// Uint8Array(3) [72, 101, 108]
console.log(decoder.decode("G8gV29ybGR ", { stream: true }));
// Uint8Array(6) [108, 111, 32, 87, 111, 114]
console.log(decoder.decode(""));
// Uint8Array(2) [108, 100]
规范
| 规范 |
|---|
| Uint8Array 与 base64 的相互转换 # sec-uint8array.prototype.setfrombase64 |
浏览器兼容性
加载中…