名前 atob そして btoa 通常のテキスト変換を提案できます。彼らのブラウザ規約はより狭く、Base64 テキストと、文字値が個々のバイトを表す文字列との間で変換されます。そのバイト文字列はコンテナであり、結果が読み取り可能な Unicode テキストであることを保証するものではありません。
2 つの異なる文字列
JavaScript 文字列は UTF-16 コード単位を使用します。バイト文字列では、各文字値が 0 ~ 255 に意図的に制限されます。 btoa('Hello') ASCII 値がその範囲に適合するため、機能します。 btoa('你好') これらの文字は 1 バイトに収まらないため、失敗します。たとえ適切な文字であっても、誤解を招く可能性があります。 btoa('é') 多くのサービスで期待される UTF-8 バイト C3 A9 ではなく、シングル バイト E9 をエンコードします。
console.log(btoa('é')); // 6Q== (byte E9)
console.log(btoa(String.fromCharCode(0xc3, 0xa9))); // w6k= (UTF-8)
バイト関数の周りに UTF-8 変換を追加する
TextEncoder テキストから UTF-8 バイトを生成します。 Base64 をデコードすると、致命的な問題が発生します。 TextDecoder 有効な UTF-8 バイトをテキストに変換し、無効なシーケンスを黙って置き換えるのではなく拒否します。この小さな例は、境界が見えるように意図的に明示されています。
const text = '中文😊';
const bytes = new TextEncoder().encode(text);
let binary = '';
for (const byte of bytes) binary += String.fromCharCode(byte);
const encoded = btoa(binary);
console.log(encoded); // 5Lit5paH8J+Yig==
const decodedBytes = Uint8Array.from(atob(encoded), c => c.charCodeAt(0));
const decoded = new TextDecoder('utf-8', { fatal: true }).decode(decodedBytes);
console.log(decoded); // 中文😊
バイナリの結果を壊れた文字列として扱わないでください
atob('/w==') バイトFFを表します。これ自体は有効な UTF-8 ではありませんが、完全に有効なバイナリ データです。正しい次のアクションは、別のテキスト変換トリックではなく、バイト ダウンロードまたは 16 進数ビューである可能性があります。そのバイト文字列を実行する TextEncoder 文字 U+00FF をエンコードし、バイトを変更します。
ブラウザ デコーダも完全なプロトコル検証ツールではありません。受け入れられる空白や省略されたパディングは、厳密なアプリケーション要件と異なる場合があります。プロトコルで正規のエンコーディングが必要な場合は、アルファベット、パディング、未使用ビットを個別に検証します。大きなファイルの場合は、完全なバイト配列を複数の領域に分散させないでください。 String.fromCharCode(...bytes);引数の数の制限は、ファイルが異常に大きくなるずっと前に失敗する可能性があります。
ブラウザ契約を読む MDN: atob() そして MDN: btoa()。アプリケーションは、寛容な変換、厳格なバリデータ、またはファイル保存ワークフローのいずれを必要とするかを決定する必要があり、これらを同じタスクであると想定する必要はありません。