Uint8Array.prototype.setFromBase64()

基准线 2025
新推出

自 ⁨2025 年 9 月⁩起,此功能适用于最新设备和浏览器版本。此功能可能不适用于较旧的设备或浏览器。

Uint8Array 实例的 setFromBase64() 方法使用来自 base64 编码字符串的字节填充此 Uint8Array 对象,并返回一个指示读取和写入了多少字节的对象。

此方法最适合填充预先分配的数组缓冲区。如果您只想从 base64 编码字符串创建新的 Uint8Array 对象,请改用静态方法 Uint8Array.fromBase64()

语法

js
setFromBase64(string)
setFromBase64(string, options)

参数

string

一个 base64 字符串,用于编码要写入 Uint8Array 的字节。它与 Uint8Array.fromBase64()string 参数具有相同的要求。请注意,字符串仅读取到数组被填满为止,因此该点之后的所有无效 base64 语法都会被忽略。

options 可选

一个自定义 base64 字符串解释过程的对象。它与 Uint8Array.fromBase64()options 参数具有相同的要求。

返回值

包含以下属性的对象:

read

从输入字符串中读取的 base64 字符数。如果解码的数据适合数组,则这是输入字符串的长度(包括填充);否则,它是适合数组的最后一个完整 4 字符块的长度。块永远不会被拆分(因为剩余位不能在不完全重新编码的情况下部分“放回” base64);如果下一个块无法放入数组的剩余部分,它将完全未被读取,导致数组的最后一两个字节未被写入。

written

写入 Uint8Array 的字节数。永远不会大于此 Uint8ArraybyteLength

异常

SyntaxError

如果输入字符串包含指定字母表之外的字符,或者最后一个块不满足 lastChunkHandling 选项,则会抛出此错误。

TypeError

在以下情况之一中抛出

  • 输入字符串不是字符串。
  • options 对象不是对象或 undefined
  • 选项不是预期的值或 undefined

示例

解码 base64 字符串

此示例使用默认的 alphabetlastChunkHandling 选项将 base64 字符串解码到现有的 Uint8Array 中。

js
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]

将大字符串解码到小数组中

如果字符串包含的数据超过了数组的容量,则方法只会写入数组能容纳的字节数,而不会丢弃任何位。

js
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() 进行写入。

js
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" 来处理不完整的块。

js
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

浏览器兼容性

另见