JavaScript には Base64 エンコードするための btoa 関数が用意されていますが、挙動が少し特殊で、単純に Unicode 文字列を渡すとエラーが発生し、また、ArrayBuffer や TypedArray を直接渡すことができません。
1. Uint8Array クラスのメソッドを用いる方法
2025 年から Uint8Array クラスに Base64 関連のメソッドが追加され、簡単に変換が行えるようになりました。
参考「Uint8Array.prototype.toBase64() - JavaScript | MDN」
参考「Uint8Array.fromBase64() - JavaScript | MDN」
※ 2026-01-08 現在、Opera および Samsung Internet で正式実装されていません。他の環境でも未実装の可能性があります。
※これらのメソッドが利用できない環境では、ポリフィルを用いるか、後述の「2. バイナリ文字列の変換を行う方法」を参照して下さい。
1.1. バイナリデータの場合
Unicode 文字列も結果的にバイナリデータとして扱うため、バイナリデータを Base64 エンコードする方法を先に説明します。
Base64 エンコードは toBase64 メソッド、Base64 デコードは fromBase64 メソッドで行います。
const uint8ArrayA = new Uint8Array([0x00, 0x10, 0x20, 0x30]);
console.log(uint8ArrayA.toString());
const base64 = uint8ArrayA.toBase64();
console.log(base64);
const uint8ArrayB = Uint8Array.fromBase64(base64);
console.log(uint8ArrayB.toString());
0,16,32,48
ABAgMA==
0,16,32,48
ArrayBuffer のデータを Base64 エンコードしたい場合は Uint8Array に変換します。
const arrayBufferA = new Uint16Array([0x1000, 0x3020]).buffer;
const uint8ArrayA = new Uint8Array(arrayBufferA);
console.log(uint8ArrayA.toString());
1.2. Unicode 文字列の場合
TextEncoder.prototype.encode を用いて Uint8Array に変換することで、Unicode 文字列をバイナリデータとして Base64 エンコードすることができます。
Base64 デコードする場合は TextDecoder.prototype.decode を用いて Uint8Array から Unicode 文字列に戻します。
const textEncoder = new TextEncoder();
const encodeString = string => textEncoder.encode(string);
const textDecoder = new TextDecoder();
const decodeString = buffer => textDecoder.decode(buffer);
//
const stringA = 'Unicode 文字列';
console.log(stringA);
const uint8ArrayA = encodeString(stringA);
const base64 = uint8ArrayA.toBase64();
console.log(base64);
const uint8ArrayB = Uint8Array.fromBase64(base64);
const stringB = decodeString(uint8ArrayB);
console.log(stringB);
Unicode 文字列
VW5pY29kZSDmloflrZfliJc=
Unicode 文字列
参考「TextEncoder: encode() メソッド - Web API | MDN」
参考「TextDecoder: decode() メソッド - Web API | MDN」
2. バイナリ文字列の変換を行う方法
Unicode 文字列やバイナリデータを btoa 関数で扱える状態に変換してから btoa 関数で Base64 エンコードします。
デコードを行う atob 関数に関しても同様の逆の変換が必要です。
2.1. バイナリデータの場合
Unicode 文字列も結果的にバイナリデータとして扱うため、バイナリデータを Base64 エンコードする方法を先に説明します。
2.1.1. Base64 エンコード
Base64 エンコード を行う btoa 関数は文字列を引数として渡しますが、その文字列の文字 1 つ 1 つを 1 バイトのデータとみなします (JavaScript の文字列の文字自体は 2 バイトです) 。
そのため、例えば Uint8Array であればその各要素を各文字に割り当てた文字列に変換すれば btoa 関数に渡すことができます (1 バイトずつに 1 バイトのデータが入っている状態から 2 バイトずつに 1 バイトのデータが入っている状態に変換する) 。
文字コードを文字として扱うために String.fromCharCode を用いて変換します。
const decodeBinaryString = uint8Array => uint8Array.reduce(
(binaryString, uint8) => binaryString + String.fromCharCode(uint8),
'',
);
//
const uint8ArrayA = new Uint8Array([0x00, 0x10, 0x20, 0x30]);
console.log(uint8ArrayA.toString());
const binaryStringA = decodeBinaryString(uint8ArrayA);
const base64 = btoa(binaryStringA);
console.log(base64);
0,16,32,48
ABAgMA==
ArrayBuffer のデータを Base64 エンコードしたい場合は Uint8Array に変換します。
const arrayBufferA = new Uint16Array([0x1000, 0x3020]).buffer;
const uint8ArrayA = new Uint8Array(arrayBufferA);
console.log(uint8ArrayA.toString());
2.1.2. Base64 デコード
Base64 デコードする場合は文字として扱っているバイトを本来のバイト列に戻します (2 バイトずつに 1 バイトのデータが入っている状態から 1 バイトずつに 1 バイトのデータが入っている状態に変換する) 。
文字を文字コードに変換するために String.prototype.charCodeAt を使用します。
Base64 デコードは atob 関数で行います。
const encodeBinaryString = binaryString => Uint8Array.from(
binaryString,
binaryChar => binaryChar.charCodeAt(0),
);
//
const base64 = 'ABAgMA==';
console.log(base64);
const binaryStringB = atob(base64);
const uint8ArrayB = encodeBinaryString(binaryStringB);
console.log(uint8ArrayB.toString());
ABAgMA==
0,16,32,48
参考「TypedArray.from() - JavaScript | MDN」
2.2. Unicode 文字列の場合
2.2.1. Base64 エンコード
前述の通り JavaScript で扱う文字列の文字は 2 バイトのため、btoa 関数の仕様から、日本語等を含む Unicode 文字列を直接 btoa 関数に渡すとエラーが発生します。
TextEncoder.prototype.encode を用いて Uint8Array に変換することで、Unicode 文字列をバイナリデータとして Base64 エンコードすることができます。
const textEncoder = new TextEncoder();
const encodeString = string => textEncoder.encode(string);
const decodeBinaryString = uint8Array => uint8Array.reduce(
(binaryString, uint8) => binaryString + String.fromCharCode(uint8),
'',
);
//
const stringA = 'Unicode 文字列';
console.log(stringA);
const uint8ArrayA = encodeString(stringA);
const binaryStringA = decodeBinaryString(uint8ArrayA);
const base64 = btoa(binaryStringA);
console.log(base64);
Unicode 文字列
VW5pY29kZSDmloflrZfliJc=
参考「TextEncoder: encode() メソッド - Web API | MDN」
2.2.2. Base64 デコード
Base64 デコードする場合は TextDecoder.prototype.decode を用いて Uint8Array から Unicode 文字列に戻します。
const textDecoder = new TextDecoder();
const decodeString = buffer => textDecoder.decode(buffer);
const encodeBinaryString = binaryString => Uint8Array.from(
binaryString,
binaryChar => binaryChar.charCodeAt(0),
);
//
const base64 = 'VW5pY29kZSDmloflrZfliJc=';
console.log(base64);
const binaryStringB = atob(base64);
const uint8ArrayB = encodeBinaryString(binaryStringB);
const stringB = decodeString(uint8ArrayB);
console.log(stringB);
VW5pY29kZSDmloflrZfliJc=
Unicode 文字列
参考「TextDecoder: decode() メソッド - Web API | MDN」
3. escape および unescape を用いる方法は非推奨
Unicode 文字列を扱う場合の btoa 関数のエラー対策として escape および unescape を用いる方法がありますが、escape および unescape 自体が非推奨になっているため使用しない方が良いです。
(ちなみに実行結果自体は前述の方法と一致するため、「エンコード結果が異なること」が非推奨な理由ではないです。)
const stringA = 'Unicode 文字列';
console.log(stringA);
const binaryStringA = unescape(encodeURIComponent(stringA));
const base64 = btoa(binaryStringA);
console.log(base64);
const binaryStringB = atob(base64);
const stringB = decodeURIComponent(escape(binaryStringB));
console.log(stringB);
Unicode 文字列
VW5pY29kZSDmloflrZfliJc=
Unicode 文字列
参考「解決策その 1 - 文字列をエンコードする前にエスケープする - Base64 - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN」
参考「escape() - JavaScript | MDN」
参考「unescape() - JavaScript | MDN」