Node.js BufferでのBase64
Node.jsでBuffer、ストリーム、グローバルbtoa/atob関数を使ったBase64エンコード・デコードをマスター。ファイル処理、文字列操作、パフォーマンスのコツを解説します。
Language
詳細な説明
Node.jsは初期バージョンから利用可能な Buffer クラスを通じて堅牢なBase64サポートを提供します。Node.js 16からはグローバルな btoa() と atob() 関数も利用できますが、サーバーサイドコードでは Buffer が引き続き推奨されるアプローチです。
BufferによるBase64の基本的なエンコードとデコード:
// String to Base64
const encoded = Buffer.from("Hello, World!").toString("base64");
// "SGVsbG8sIFdvcmxkIQ=="
// Base64 to string
const decoded = Buffer.from("SGVsbG8sIFdvcmxkIQ==", "base64").toString("utf-8");
// "Hello, World!"
URL-safe Base64:
// Encode as Base64url
const urlSafe = Buffer.from("Hello, World!").toString("base64url");
// "SGVsbG8sIFdvcmxkIQ" (no padding, - and _ instead of + and /)
// Decode Base64url
const fromUrlSafe = Buffer.from("SGVsbG8sIFdvcmxkIQ", "base64url").toString("utf-8");
"base64url" エンコーディングオプションはNode.js 14で追加され、文字の置換とパディング除去を自動的に処理します。
ファイルのエンコードとデコード:
const fs = require("fs");
// File to Base64
const fileBase64 = fs.readFileSync("image.png").toString("base64");
// Base64 to file
fs.writeFileSync("output.png", Buffer.from(fileBase64, "base64"));
大きなファイルのストリーミング処理: メモリに読み込めないほど大きなファイルには、組み込みのtransformを使ったストリームを利用します:
const { Transform } = require("stream");
const fs = require("fs");
// Custom Base64 encoding stream
class Base64Encode extends Transform {
constructor() {
super();
this.remainder = Buffer.alloc(0);
}
_transform(chunk, encoding, callback) {
const combined = Buffer.concat([this.remainder, chunk]);
const usable = combined.length - (combined.length % 3);
this.push(combined.slice(0, usable).toString("base64"));
this.remainder = combined.slice(usable);
callback();
}
_flush(callback) {
if (this.remainder.length > 0) {
this.push(this.remainder.toString("base64"));
}
callback();
}
}
fs.createReadStream("large-file.bin")
.pipe(new Base64Encode())
.pipe(fs.createWriteStream("output.b64"));
Buffer vs btoa/atob:
Bufferはバイナリデータをネイティブに扱い、複数のエンコーディング(utf-8、base64、base64url、hex、latin1)をサポートbtoa()/atob()はブラウザと同様にLatin-1文字列のみを扱い、コードポイント255を超える文字でエラーが発生Bufferはストリーミングをサポートし、大きなデータに対してよりメモリ効率的- サーバーサイドコードでは
Bufferを使用。btoa()/atob()はブラウザの動作に合わせる必要があるアイソモーフィックコードでのみ使用
よくある間違い: デコード時にエンコーディングを指定せずに Buffer.from(string) を使用すること。デフォルトのエンコーディングは "utf-8" であり、入力をBase64データではなくUTF-8文字列として解釈してしまいます。デコード時は必ず第二引数に "base64" を指定してください。
ユースケース
Base64エンコードされたJSONペイロードでファイルアップロードを受信し、BufferでデコードしてクラウドストレージにストリーミングするNode.jsマイクロサービスを構築する場合に使用します。