JavaScriptのatob()で日本語が文字化けする原因と解決コード (TextDecoder)

Base64 エンコード JavaScript エラー解決

JavaScriptの atob() 関数を使って日本語(UTF-8)のBase64文字列をデコードした際に ã"ã‚"ã«ã¡ã¯ のように文字化けする原因と解決コードです。

1. オンライン Base64 デコーダー(UTF-8対応)

ブラウザ上で日本語テキストのBase64エンコード・デコードが即座に行えます(文字化けしません)。

🔄 この場でBase64デコードを試す


2. なぜ atob() で日本語が文字化けするのか?

理由:atob() の Latin-1 (1バイト) 制限

JavaScript標準の atob() は、1文字を 1バイト (Latin-1 / ASCII) として処理します。

一方で日本語(UTF-8)は 1文字につき3バイト のデータ長を持ちます。atob() はこの3バイトの連続を単なる「3つの独立した1バイト文字」として誤って解釈して出力するため、文字化け(Moibake)が発生します。


3. ブラウザ(フロントエンド)での解決コード

atob() で得たバイナリ文字列を Uint8Array のバイト配列に変換し、TextDecoder('utf-8') を通して復元します。

function decodeBase64Utf8(base64String) {
  // 1. atobでバイナリ文字列にデコード
  const binaryString = atob(base64String);
  
  // 2. バイト配列 (Uint8Array) に変換
  const bytes = Uint8Array.from(binaryString, char => char.charCodeAt(0));
  
  // 3. UTF-8 としてデコード
  return new TextDecoder('utf-8').decode(bytes);
}

// テスト
const base64 = "44GT44KT44Gr44Gh44Gv"; // 「こんにちは」のBase64
console.log(decodeBase64Utf8(base64)); // "こんにちは"

4. Node.js での解決コード

Node.js環境では Buffer モジュールを使用すると1行で安全に処理できます。

const base64 = "44GT44KT44Gr44Gh44Gv";
const decodedText = Buffer.from(base64, 'base64').toString('utf-8');

console.log(decodedText); // "こんにちは"

5. 注意:Base64URL (- _) とパディング (=)

JWTやURLで使われる Base64URL 形式の文字列は、+- に、/_ に置換されており、末尾のパディング = が省略されている場合があります。atob() に渡す前に変換が必要です。

function base64UrlDecode(base64Url) {
  // Base64URL記法を通常のBase64記法へ変換
  let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
  
  // パディング (=) の補充
  while (base64.length % 4 !== 0) {
    base64 += '=';
  }
  
  return decodeBase64Utf8(base64);
}