もう、文字化けは飽き飽きです。
JIS X 0213:2004 な文字をCGIで処理するとおかしいことになるって現象があったので、調査しました。始めは、Jcode.pm とか Encode.pm の問題かと思ったんですが、分解して検証してみるとこの辺の動きには問題なさそう。徐々に上流に戻りながら調べてみたところ、どうやらCGIに到達しているデータ時点が化けているっぽいことが判明しました。送り主はIE6 (XP) 。
#!/usr/local/bin/perl use strict; print "Content-type: text/html; charset=Shift_JIS?n?n"; my $query = $ENV{QUERY_STRING} || join('', <STDIN>); $query =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; print <<__FORM__; <html> <head> <title>CGI TEST</title> </head> <body> <form action="test.cgi" method="GET"> <input name="test" > <input name="test2" > <input type="submit"> </form> <hr> <pre> $query </pre> </body> </html> __FORM__
こんな至極単純なCGIでテストすると*1、「あああ」「熿」を送ると「test=、「、「、「&test2=滕」になりました。これは、ここで槍玉に挙がってるケース1と同じ現象です。
ああ、IEひでーなーとあきらめかけていたら、偶然対処法を発見。フォームのあるHTMLに、 <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> を入れるだけで、なんとこの現象が直ってしまいます。不思議不思議。「熿」は実体参照で送られてきます。
なお、同じことをSafariでやると、普通に「?」表示でした。
*1:問題切り分けのため、敢えてモジュールを何も使ってない