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}`);
}
コメント