JavaScript において、Internet Explorer と Netscape ブラウザでは、escape() の動作が異なります。たとえば、シフトJISで "いろは" という文字をエンコードすると次のようになります。
ブラウザ | エンコード例 | 説明 |
---|---|---|
Netscape | %82%A2%82%EB%82CD | シフトJISのまま8ビットずつ16進変換。 |
IE4.0~ | %u3044%u308D%u306F | Unicodeに変換して16ビットずつ16進変換。 |
CGI 側で Unicode に対応すればよいのですが、Unicode からシフトJIS への変換は巨大な変換テーブルが必要で、ちょっと骨が折れます。そこで、なんとかして、IE でも Netscape と同じようなエンコード結果を得る方法を考えてみました。
コードを下記に示します。受け取った文字列を隠しフォーム(form1)に代入してサブミットし、結果を隠しフレーム(frame1)に表示しています。フレームの URL は test.htm?t1=%82%A2%82%EB%82CD のようにエンコードされるので、ここから、%82%A2%82%EB%82CD の部分を取り出して表示しています。
<script> var flag = 0; function conv1(str) { if (document.all) { document.action = location.href; document.form1.t1.value = str; document.form1.submit(); flag = 1; conv2(); } else { alert(escape(str)); } } function conv2() { var n = frame1.location.href.indexOf("="); if (n != -1) { if (flag == 1) { alert(frame1.location.href.substr(n + 1)); flag = 0; } } else { setTimeout("conv2()", 10); } } </script> <form name="form1" target="frame1" method="GET"> <input type="hidden" name="t1"> </form> <iframe name="frame1" onload="conv2()" width=0 height=0 style="visibility:hidden"></iframe> <form> <input type="text" name="t1" value="いろは"> <input type="button" value="OK" onclick="conv1(this.form.t1.value)"> </form>
IE5.0 が <iframe> の onload に対応していなかったので、setTimeout() でロードが完了するのを見張るように修正しました。(2003.3.21)
結果表示のダイアログが 2~3回表示されてしまう不具合を修正しました。(2004.11.23)