日記にこういう小難しいことを書くのは「俺ってどう? こんなことやっててスゴイでしょ?」という自慢である。もちろん技術情報を提供しようという高尚な考え方の人もいると思うけど、私は違う。ハッキリ言って自己顕示欲の現れだ。だって自慢したいんだから仕方ない。自分のことをひけらかそうと思わないなら、そもそもサイトを作ろうなんて思わないだろうし。
でも人によってはこういう情報が役に立つかもしれないので、今回はいつもより気合い入れて書いてみます。
某掲示板を運営していて、携帯からの利用者の意見が来た。どうやらiモードからだとマトモに表示されていないらしい。元のスクリプトは CGI に直接アクセスすれば見られると説明にはあったが、私がケータイコンテンツというものに興味がないというか、むしろバカにしていたぐらいなので全く動作確認などしていなかった。iモード携帯は持っていない上、使っている au に関しては EZweb どころかやメールさえ滅多に使わない。したがってどんな表示になるのかも全く想像がつかない。
困ったなぁと思いつつ、とりあえず DoCoMo の開発者用サイトで HTML の仕様書を見ようとしたら、そこに PC 上で携帯の表示をシミュレートする Windows 用のソフトがフリーで置いてあった。これはありがたい。
iモードHTMLシミュレータ
http://www.nttdocomo.co.jp/service/imode/make/content/html/tool/
iモードHTMLシミュレータII
http://www.nttdocomo.co.jp/service/imode/make/content/html/tool2/
NTT謹製のiモードHTMLシミュレータには古いバージョンとIIがあったので両方入れてみた。IIの方は FOMA などの画面が大きく新しめの機種を再現しているらしい。起動して早速その掲示板にアクセスしてみると確かにこれはひどい。というかよくこんな画面でアクセスする気になるものだ。まあIIの方だとなんとか「見れる」程度なのだが、問題は古い方。こちらについては文字が完全に化けてしまって読むことすらできない。
調べてみたら DoCoMo 携帯は基本的にシフトJISにしか対応しないという。この掲示板はアスキーアートなどで半角カタカナが多用されることを考えて、全ての文字コードを EUC に書き直していた。他にも色々スクリプトを書き直しているため、携帯表示用のスクリプトでことごとくエラーを吐いている。FOMA などの最新機種は EUC にも若干対応しているようで、何とか表示できていたようだ。旧機種は無視してとりあえず文字は「読めればいい」ので、まずはHTML表示のエラーを直す。匿名でも投稿を受け付けるようにしているため、名前が空欄になる部分を if〜else で「名無しさん」と埋めるように改造。これでとりあえず解決。
と、思ってローカルの Apache のバーチャルアドレスから表示確認しようとしたら表示エラー。サーバが存在しないと出る。おかしいなと思ってiモードHTMLシミュレータIIの[ブラウザ]>[オプション設定]>[ネットワーク設定]を確認したところ「HOSTSファイルを参照する」のチェックが外れていた。ここにチェックを入れて内部参照できるようになって解決。私のようにローカルのCGIテスト環境でWindowsのHOSTS設定している人は要注意だろう。
IIで正しく表示されることも確認できて、本サーバにアップ。試しに EZweb で初めてアクセスしてみると、むむう、こちらは完全に文字化けしてしまう。どうやら EZweb はシフトJISのみしか対応していないらしい。こうなると悔しいので、こうなったら文字コードも直すことを決意する。
ただしログから何から全部をシフトJISに戻すのはハッキリ言って無茶な上に改造した意味がない。というか数パーセントの利用者のため、たかがケータイのためにPC上で正常に動いているものを全部作り変えるのは無茶だ。スクリプトをいろいろ解析した結果、jcode.pl で全角カナを半角カナに変換している関数を見つけた。なるほど、CGI でログをいじらずに表示だけを切り分けているようだ。ファイルの I/O は増えるが表示前にテキストを一気にコンバートすれば済みそうだ。
いろいろいじっているうちに、このスクリプトの構造が分かってきた。 CGI ファイルにアクセスするとまず UserAgent で携帯か否かを判定している。UA の先頭に DoCoMo、KDDI、J-PHONE という文字列があれば携帯表示用のサブルーチンに進む。機種によって若干の表示調整を行っているようだが、すでにその分岐が DoCoMo 505i 以前のものと仕様が古く、正常に動作していないようだった。とりあえずそれらをコメントアウトして、
&jcode::convert(\$imode_html,'sjis');
&jcode::z2h_sjis(\$imode_html);
と、すでにサブルーチンで $imode_html に格納されている〜のタグとテキストを一気にシフトJISに変換し、カタカナも携帯表示用に半角カタカナへコンバート。そしてiモードの場合はHTTPヘッダ情報に受信ファイルのバイト数を示す「Content-length」が必須になるため
my $len = length $imode_html;
と、バイト数を調べ
print "Content-length: $len¥n";
print "Content-type: text/html¥n¥n";
print $imode_html;
exit;
と書き出す。意外にあっさりと変換されて表示もスムーズ。これで旧バージョンのiモードHTMLシミュレータだけでなく、EZweb からの表示もOKとなった。
こうしていじりだすとだんだん携帯コンテンツをつくるのが面白くなってきた。いろいろと調べてみると携帯のダイヤルボタンでダイレクトにリンクさせる独自の「accesskey」というタグを発見。
<a href="index.html" accesskey="1">ホーム</a>
のように記述すると、携帯利用者には当たり前の事なのだろうけど、これで[1]のダイヤルボタンを押すだけでダイレクトに index.html にアクセス。いちいち上下キーでリンクを移動する手間を省くことができるらしい。さらに携帯の独自コードでダイヤルボタンの「絵文字」を表示できるようで、ユーザはこれを見て「ダイヤルボタンで直リンク」と判断するようだ。ダイヤルボタンの絵文字の 1 は 驪 というコードになるため、
<a href="index.html" accesskey="1">驪 ホーム</a>
のように記述。するとシミュレータで「1 ホーム」のように表示され、いかにもケータイサイトらしい作りになった。EZweb も同じ絵文字コードのため(厳密には「互換」であって、これが後に私を苦しめるのだが…)、試しに自分の au ケータイでブラウジングしてみるとちゃんと絵文字も表示され、ボタンでサクサク移動できてなかなかよろしい。恐らく以前よりも非常に軽快な操作になっただろう。
2つのキャリアに対応できるようになると欲が出て、SoftBank 携帯への対応もやりたくなってきた。調べてみると SoftBank にもウェブコンテンツビューアというツールが用意されていた。
ウェブコンテンツビューア
http://developers.softbankmobile.co.jp/dp/tool_dl/web/tool.php
NTTのものより様々な機種/メーカーが選択できて機能も豊富。絵文字も入力ツールが始めからついている(iモードは別ツール)。そのため最初は慣れるのに戸惑った。
使い勝手が分かって、いろいろな機種で現在の状態を確認すると、iモードやauでは表示されていたダイヤルボタンのところが「驪」とそのままコードが丸見えになってしまうことに気づいた。調べてみると J-PHONE 時代から絵文字コードが他キャリアと互換性がないとのこと。これは困った。だったらわざわざ絵文字を使うのはあきらめて「1.」と書いておけばいいのだろうが、それではせっかく組み込んだのにイヤだ。
色々調べてみたところ、どうやらバイナリコードをそのまま埋め込めば表示ができることを発見。[1]ボタンなら$F<と埋め込めばいいらしい。ただしそのまま CGI に埋め込むとエスケープ文字や特殊文字とかち合ってエラーを吐く文字もあるため、
$a_key1 = ‘$F<';
のようにシングルクォーテーションでくくって変数化。これで DoCoMo/au と SoftBank を UA で判定して分岐させ、$a_key1 を入れ替えて表示させればOK…と思いきやまた問題。全く設定した文字が表示されない。分岐が反映されないのだ。どうもおかしいと思って、ウェブコンテンツビューアの「HTTPログ」を確認すると
User-Agent: J-EMULATOR/4.0/J-K51/SN12345678901 KW/ Profile/...
などと表示されている。UA で J-PHONE、Vodafone、MOT-、SoftBank と先頭につくものを SoftBank ケータイと振り分けていたのだが、どうやらウェブコンテンツビューアの UA は J-EMULATOR やら Semulator などワケのわからんものになっている。仕方ないため、以下のようにして分岐させてみる。
if ($ENV{'HTTP_USER_AGENT'} =~ /^(?:DoCoMo|KDDI|UP)/) {
$a_key1 = qq|驪|;
$a_key2 = qq|麗|;
$a_key3 = qq|黎|;
.....
}
elsif (($ENV{'HTTP_USER_AGENT'} =~ /(?:J-PHONE|Vodafone|MOT-|SoftBank)/i) || ($ENV{'HTTP_USER_AGENT'} =~ /emulator/i)) {
$a_key1 = '$F<';
$a_key2 = '$F=';
$a_key3 = '$F>';
.....
}
乱暴ではあるが大文字小文字関係なく「emulator」とマッチすれば無理矢理 SoftBank ケータイということにしておく。まあ他のブラウザでヒットしたとしても、ロクなものではないだろうし…
そんなこんなでようやくそれっぽくなってきたのだが…まだまだ格闘の日々は続くのであった(って続くの?)。