2012年1月29日

PCでスマートフォンサイトを閲覧してみた


最近、iPhoneやAndroidの普及のおかげで主要なサイトではスマートフォン版のページが提供されるようになりました。ほとんどのサイトはUser-Agentヘッダをスマートフォンのそれに変更する事で、PC上でもスマートフォン版のページを閲覧する事ができます。
(ちなみにいわゆるガラケー版のページは、携帯各社のゲートウェイIPアドレスからしか閲覧できないようにされている事がほとんどのため、PC上からは閲覧する事はできません)

ただ、一部のスマートフォン版ページはUser-Agentヘッダを変更しただけでは閲覧ができないようになっているところがあり、ガラケーと違ってIPアドレス制限ができないスマートフォンでどうやって実現しているか気になり、今回はそのカラクリを調査してみました。

■サーバ-ブラウザ間の通信を書き換え
制限をかけているサーバ側でPCかスマートフォンかを判別するためには、接続元IPアドレスを除くとUser-Agentヘッダなどの情報から類推しているものと思われます。であれば、PCブラウザが出力するヘッダ情報をスマートフォンのそれと全く同一にすればPC上で表示ができるはずです。

そのためには、PCブラウザからサーバに送信するヘッダ情報を通信のタイミングで書き換えてやる必要があります。この辺の処理はProxomitronFiddlerなどを使えばいいのですが、今回は勉強も兼ねてRubyのWEBrickでプロキシサーバを実装して行いました。

■WEBrickでプロキシサーバ
とはいってもRuby初心者の自分がイチから作れるはずもないので、WEBrick::HTTPProxyServer で無理矢理リクエストヘッダを書き換えるプロクシサーバ - PARAGRAPHSのソースを拝借させて頂き、手持ちのスマートフォンが出力するヘッダ情報に書き換えるようにしてみました。
(手元のRuby1.9.2環境では、そのままだと通信時に"ERROR undefined method `each_line' for #<array:0x30865bc>"エラーが発生するため、@raw_headerを@raw_header.joinに修正して実行しました)

■閲覧できず。。
ところが、いざ対象のページにアクセスしてみたものの、「お使いの環境では閲覧できません」エラー表示。。ブラウザのデバッガを使って通信ステータスを確認してみましたが、リダイレクトなどの処理は行われていませんでした。となると次に考えられるのはjavascriptによる制御。ただ、PCブラウザならスマートフォンのそれをほとんど実行できるはずですし、とりあえずその処理を行っている箇所を探す事にしてみました。
(試しにjavascriptをOFFにしてアクセスしてみましたが同じ結果でした)

■タッチイベント
javascriptを使って制御を行うのであれば、ブラウザが最初にアクセスした時に取得したHTML上にその処理が記述されているはずなので、プロキシサーバに手を加えて通信結果をファイルに保存するようにして中身を確認してみたところ、なんと下記のような制御を行っていました!

  • javascriptがOFFの場合は、<noscript><meta http-equiv="refresh">タグでエラーページへ転送
  • ontouchstart/ongesturestartなど、タッチ系イベントがdocumentオブジェクトに宣言されているかチェック
  • その他もろもろの機能(端末の回転イベント)やFlash対応有無をチェック
  • 上記条件を満たしていない場合は、document.location.hrefでエラーページへ転送
  • <body>タグ内には正常ページへPOSTするフォームが記述されており、onloadイベントでsubmitするように記述

単純にjavascriptでごにょごにょやっているだけかと思いきや、javascriptをOFFにされた場合やFlash未対応機種の場合などもしっかり考慮されており、予想以上に複雑な事をやっていたのが驚きでした。というわけでカラクリが分かれば後はそれを回避すれば閲覧できるはずですので、今回はHTML中にdocument.location.hrefを見つけたら//(コメント)を挿入して無効化するようにしました。

■閲覧はできたものの
上記処理を加えて再度ページを開いてみたところ、やっとPCブラウザ上で閲覧する事ができました。とはいえ、ページを進めていくとFlashやHTML5の表示で進む事ができなかったりと、都度そういった箇所を回避する処理を記述していく必要がありそうです。本当はRubyの感想などをつらつら書くつもりだったのですが、なんかアングラな内容になってしまいました。。