au 端末で XHTML なページが文字化けする件の考察
具体的には imoTwit を au 端末で見ると文字化けしてしまう、と云う話。
ようやく理由が判ったので、ちょっとパターン検証してみました。(簡易的な CGI を作成してチェックしました)
ページの文字コード | Content Type | 文字化けの有無 |
---|---|---|
UTF-8 | application/xhtml+xml | あり |
UTF-8 | text/html | なし |
Shift JIS | application/xhtml+xml | なし |
Shift JIS | text/html | なし |
いい感じで XHTML + UTF-8 の場合だけ文字化けしています。。。
ちなみに、 imoTwit のレスポンスヘッダを確認したところ、 Cookieless でセッションを扱う場合のみ、 application/xhtml+xml になっている模様。(なんだそれ。。。)
一方、 Cookieを利用する場合は text/html で返ってきている様です。…… ASP.NET の仕様?
うーむ。この設定を変更できれば解決な気はするけど、調べるの面倒そう。(ぉ
もし変更出来ないとなると、 UA チェックして文字コードを変える、とかになってしまいそうですね。(確か、それは初音さんのポリシーに反するはず)
……結局、 au は dis られる、で F/A なのかなぁ。。。
※ちなみに、チェックに使用した CGI は以下な感じ。(途中で面倒になっていい加減な書き方をしています ^^; )
#!/usr/bin/perl use strict; use warnings; use utf8; binmode STDIN, ":utf8"; binmode STDOUT, ":utf8"; use CGI; &main(); sub main() { my $cgi = new CGI; my $param = &check_param($cgi); binmode STDOUT, sprintf(':encoding(%s)', $param->{'charset'}); printf 'Content-Type: %s' . "\n", &get_contentype($param); print "\n"; &print_content($param); } sub check_param($) { my $_cgi = shift; my $param = { charset => 'utf8', type => 'xhtml' , cgi => $_cgi }; my $value = $_cgi->param('charset'); unless (defined $value) { $value = ''; } if ($value eq 'shiftjis' || $value eq 'shift_jis' || $value eq 'Shift_JIS' || $value eq 'SJIS') { $param->{'charset'} = 'shiftjis'; } $value = $_cgi->param('type'); unless (defined $value) { $value = ''; } if ($value eq 'html') { $param->{'type'} = 'html'; } return $param; } sub get_contentype($) { my $_param = shift; my $contenttype = ''; if ($_param->{'type'} eq 'xhtml') { $contenttype = 'application/xhtml+xml'; } else { $contenttype = 'text/html'; } $contenttype .= sprintf '; charset=%s', &get_htmlencoding($_param->{'charset'}); return $contenttype; } sub get_htmlencoding($) { my $_encoding = shift; my $htmlencoding = 'utf-8'; if ($_encoding eq 'shiftjis') { $htmlencoding = 'Shift_JIS'; } return $htmlencoding; } sub print_content($) { my $_param = shift; printf '<?xml version="1.0" encoding="%s" ?>' . "\n", &get_htmlencoding($_param->{'charset'}); print '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">' . "\n"; print '<head>' . "\n"; printf '<meta http-equiv="Content-Type" content="%s" />' . "\n", &get_contentype($_param); print '<title>Test Page</title>' . "\n"; print '</head>' . "\n"; print '<body>' . "\n"; print '<h1>■Test Page■</h1>' . "\n"; print '<p>■ログイン</p>' . "\n"; print '<p>▼パスワード:</p>' . "\n"; print '<dl>' . "\n"; print '<dt>query</dt>' . "\n"; printf '<dd>%s</dd>' . "\n", ($ENV{QUERY_STRING} or ''); print '<dt>charset</dt>' . "\n"; printf '<dd>%s</dd>' . "\n", $_param->{'charset'}; print '<dt>type</dt>' . "\n"; printf '<dd>%s</dd>' . "\n", $_param->{'type'}; print '</dl>' . "\n"; print '</body>' . "\n"; print '</html>' . "\n"; }
( 2008-12-03T15:50 追記)
一番大事なことを書き損ねました。
この情報は、 id:gifnksm さんの記事で知りました。
貴重な情報、ありがとうございます♪