ブラウザで日本語をbase64変換する(javascript)

JavaScript

base64に変換するメソッドとしてはwindow.btoa()があるのですが、これに日本語文字列を渡すとエラーを吐きます。Latin1の範囲じゃないとダメらしい。

Uncaught DOMException: Failed to execute ‘btoa’ on ‘Window’: The string to be encoded contains characters outside of the Latin1 range.

nodejsの場合、以下のコード終了なのですが、ブラウザの場合は少し遠回りが必要です。

Buffer.from("日本語文字列").toString('base64');

とにかく日本語をascii文字列に変換してしまえばbtoaが使えるので、この2パターンを考えました。

  • window.unescape(encodeURIComponent(jpString))
  • String.fromCharCode.apply(null, Array.from(new TextEncoder().encode(jpString)))

懸念としては
1つ目の方法はunescapeメソッドが非推奨なことですね。
2つ目の方法は処理時間が長いです。
以下に計測コードを置いておきますが、chromeで試した場合では文字数によらず常にunescapeの方が2~3倍速い結果となりました。

  const jpString = '日本語文字列';

  performance.mark('start');

  for (let i = 0; i < 10000; i++) {
    const func1 = window.btoa(window.unescape(encodeURIComponent(jpString)));
  }

  performance.mark('func1end');

  for (let i = 0; i < 10000; i++) {
    const func2 = window.btoa(String.fromCharCode.apply(null, Array.from(new TextEncoder().encode(jpString))));
  }

  performance.mark('func2end');

  performance.clearMeasures();

  performance.measure('func1Time', 'start', 'func1end');
  performance.measure('func2Time', 'func1end', 'func2end');

  for (const entry of performance.getEntriesByType('measure')) {
    console.log(`${entry.name}: ${entry.duration}`);
  }

コメント