
現象紹介
PHP(サーバーサイド)で日本語を含む文字列のデータを一度Json形式に変換して、それをBase64に変換します。 仕事のプログラムを書くわけにいかないので、簡単にサンプルを作っておきます。<?php
$data = ["りんご","いちご","バナナ","みかん","ぶどう"];
$json = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$base64 = base64_encode($json);
echo "<h3 id='base64'>{$base64}</h3>";
?>
<div id="decode_data"></div>
<script>
const base64 = document.getElementById('base64').innerText
const json = atob(base64)
const string = JSON.stringify(json, null, 2)
document.getElementById("decode_data").innerHTML = string
</script>
<style>
#base64,
#decode_data{
padding:10px;
margin:10px;
white-space:pre-wrap;
word-break:break-all;
border:1px dashed #ccc;
font-size:14px;
}
</style>
結果はっぴょう〜!
元のデータ(JSON)$data = ["りんご","いちご","バナナ","みかん","ぶどう"];
PHPでエンコードしたBase64
WyLjgorjgpPjgZQiLCLjgYTjgaHjgZQiLCLjg5Djg4rjg4oiLCLjgb/jgYvjgpMiLCLjgbbjganjgYYiXQ==
Javascriptでデコードした文字列
全く読めない文字列が表示されました・・・
文字化けの原因
どうやら、2倍と文字を使うと、Base64エンコード/デコード時に変換がうまくいかないようです。 PHPとJavascriptという別言語の間におけるトランスレーションも大きな問題になっていました。 2バイト文字列を、エンコード・デコード時にUTF-8を明示的に指定する必要があります。 今回のケースでは、文字エンコードが"UTF-8"で扱う事で、問題ないのですが、まだそれ以外の文字エンコードを使っているWebサイトがあるのを見かける事があるので、 その場合は、適宜文字コードを置き換えてお試しください。解決方法
PHPでのbase64のエンコード記述は、何の問題もありません。 PHP$base64 = base64_encode(json_encode($json, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
問題はJavascriptです。
以下のように変更してみました。
Javascript (Before)
const base64 = document.getElementById('base64').innerText
const json = atob(base64)
Javascript (After)
const base64 = document.getElementById('base64').innerText
const json = atob(base64)
const utf8Decoder = new TextDecoder("utf-8")
const string = utf8Decoder.decode(new Uint8Array([...json].map(char => char.charCodeAt(0))))
document.getElementById("decode_data2").innerHTML = string
Javascriptの修正したコードで実行
きれいに、元通りの文字列が表示されました。
TextDecoder()なんて関数、普段ほぼ使わないですけど、
こういう時に使える様になっておくのも悪くないです。
0 件のコメント:
コメントを投稿