csWindows31J

HTTPレスポンスヘッダのcontentType

JSPの先頭には次のような1行を書くのが通例だ。

<%@ page contentType="text/html; charset=Windows-31J" pageEncoding="Windows-31J" %>

このcontentTypeの部分が最終的にはHTTPレスポンスヘッダに展開される。
機種依存文字が文字化けするからShift_JISではなくWindows-31Jを使いましょう、と。だからAjaxプログラミングをしようと思った場合もサーバー側のプログラムは当然こんな風に作るだろう。

  response.setContentType("text/html; charset=Windows-31J");
  PrintWriter writer = response.getPrintWriter();
  writer.println("{age:27}");
  writer.close();

ちなみにクライアント側のサンプルも載せておきます。jQueryを使用したajax呼び出し。

  $.getJSON('http://localhost:5555/sample/getajaxdata', {}, function(result){ alert(result.age); });

これで画面には「27」と表示される。
・・・と思いきやこのプログラムはIEでは動作しない。こういうのはまるわー。結論を先に言うとサーバー側プログラムのcharsetをWindows-31JではなくcsWindows31Jとすればよいのだ。http://d.hatena.ne.jp/kusakari/20070720/1184928455#tbに詳しくあります。本当に助かりました。

csWindows31Jって?

ところで初めて聞いたけどこのcsWindows31Jって何よって話。名前から考えるとWindows-31Jの別名だと想像できる。事実、http://d.hatena.ne.jp/Kazzz/20050614/p1を読んでみると

これはIANAでは"Windows-31J"のエイリアスとして登録されている名前なので

とあり、やはりWindows-31Jの別名のようだ。しかしその後に不可解なことが書いてある。

このエンコーディング名"csWindows31J"ですがWindowsXPのレジストリ上では"Shift_JIS"のエイリアスとして登録されているのです。

え!?
ということは、AjaxのところでWindows-31Jの代わりにcsWindows31Jを使用すればOKということになっていた訳だけど、実はWindows-31JではなくShift_JISという扱いになってしまうってことか。機種依存文字とかが文字化けするやん(汗)
・・・と思ってやってみたけど特に文字化けしなかった。あれ、Shift_JISって文字化けしなかったっけ?ちょっと不安になったのでcharsetの部分をShift_JISにして再度実験してみると予想通り機種依存文字が文字化けした。ほっ。
でもおかしいな・・・うーむ・・・
この実験結果から分かる事といえば、OS上では「csWindows31J=Shift_JIS」だけどIE上では本来の「csWindows31J=Windows-31J」ってことなんだろうな。あってるよね!?ややこしや〜。

追記 2008/12/24

さらに調査を続けて分かったことがあったのでメモ。
Ajaxリクエストの時だけcharsetをcsWindows31Jにして通常リクエストの時はcharsetをWindows-31Jにするってのは面倒なので常にcsWindows31Jにした方が統一されてていいんじゃないかとjspヘッダ部をこのようにしてみました。

<%@ page contentType="text/html; charset=csWindows31J" pageEncoding="Windows-31J" %>

このやり方で問題ないかどうかを確認するための実験をしてみます。
まずHTMLのHEAD部に次のようなメタタグを付与してみます。

<META http-equiv="Content-Type" content="text/html; charset=UTF-8">

ブラウザの文字エンコーディングの解釈は、次の順で行われると理解しています。

  1. HTTPレスポンスヘッダのcontentType
  2. METAタグのContent-Type

csWindows31Jがうまく認識されていれば正しく表示されるし、認識できていなければUTF-8と解釈して全ての全角文字で文字化けが起こるはずです。
実験結果としては、以下のようになりました。

IE firefox
×

事実、firefoxの文字エンコーディングを確認してみるとUnicode(UTF-8)が選択されていました。
当然ですが、ajax版もfirefoxでは文字化けが起こりました。
IEだけしか動作保障していないような場合はcsWindows31Jで統一してもよさそうですが、firefoxなど他のブラウザも対象になっている場合はひと工夫が必要のようです。

疑問

csWindows31Jをfirefoxが認識していないからMETAタグを参考にUTF-8だと判定したとみて間違いないと思うんですが、試しにjspヘッダ部のcharsetを

<%@ page contentType="text/html; charset=xxxx" pageEncoding="Windows-31J" %>

に変えてみたところ、200OKは返ってきてるもののfirefox上では全く何も表示されなくなりました。
同じくMETAタグが優先されると思ってたんだけどな。。
ということはcsWindows31Jを全く認識していないというわけではないのか!?うーん、分からん・・・