Window: btoa() 方法

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

Window 介面的 btoa() 方法從一個二進位制字串(即,字串中的每個字元都被視為二進位制資料的一個位元組)建立一個 Base64 編碼的 ASCII 字串。

你可以使用此方法編碼可能導致通訊問題的資料,傳輸資料,然後使用 Window.atob() 方法再次解碼資料。例如,你可以編碼控制字元,例如 ASCII 值 0 到 31。

如果你的資料在一個 Uint8Array 物件中,也請考慮使用 Uint8Array.prototype.toBase64() 方法,以避免建立包含原始位元組的字串。

語法

js
btoa(stringToEncode)

引數

stringToEncode

要編碼的二進位制字串。JavaScript 中的字串編碼為 UTF-16,因此這意味著每個字元的程式碼點必須小於 256,表示一個位元組的資料。

返回值

一個包含 stringToEncode 的 Base64 表示的 ASCII 字串。

異常

InvalidCharacterError DOMException

字串中包含的字元不適合單個位元組。有關更多詳細資訊,請參閱下面的“Unicode 字串”。

示例

js
const encodedData = window.btoa("Hello, world"); // encode a string
const decodedData = window.atob(encodedData); // decode the string

Unicode 字串

Base64,顧名思義,需要二進位制資料作為輸入。就 JavaScript 字串而言,這意味著字串中每個字元的程式碼點只佔用一個位元組。因此,如果你將一個包含佔用多個位元組的字元的字串傳遞給 btoa(),你將收到一個錯誤,因為這不被視為二進位制資料。

js
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,然後編碼這些位元組。

最簡單的解決方案是使用 TextEncoderTextDecoder 在 UTF-8 和字串的單位元組表示之間進行轉換。

js
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 Ā 𐀀 文 🦄"

轉換任意二進位制資料

上一節中的 bytesToBase64base64ToBytes 函式可以直接用於在 Base64 字串和 Uint8Array 之間進行轉換。

為了獲得更好的效能,透過 FileReaderfetch API,可以在 Web 平臺中本地實現 Base64 資料 URL 之間的非同步轉換。

js
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

瀏覽器相容性

另見