TOP > スクリプト制作メモ > パソコン(PC)向けページと携帯向けページの振り分け方法について

≫同じURLでPCでも携帯でも

ホームページと言えばPCブラウザ(主にIE,NN,Opera)で見るものと相場が決まっていたのも今は昔、インターネットに接続できる携帯端末の普及はめざましく、ホームページを運営していく上ではそういった携帯端末向けのページを用意する必要性が高まっています。

ただ、PCブラウザ(主にIE,NN,Opera)向けのページと携帯端末向けのページでは、含められる内容が著しく異なります。これは、PCブラウザ(主にIE,NN,Opera)が通常のHTMLで記述でき様々な画像や動画や音声ファイルの再生に対応しているのに対して、携帯端末ではHTMLの一部のみ使用できるCHTML(iモード)やXHTML(J-SKY)など多少制限があり、画像や動画、音声の再生にも制限があります。また、最も厳しい制限はページコンテンツの容量が極端に少ないということです。

以上の様な違いを考慮すると、PCブラウザ(主にIE,NN,Opera)向けのページと携帯端末向けのページを別々に用意しようとするのが通常だと思います。しかし、アドレスがばらばらになり、PCブラウザ(主にIE,NN,Opera)向けのページと携帯端末向けのページでそれぞれURLを告知しないといけないという手間が発生します。

では、同じURLで、アクセスしてきた環境によって見せるページを振り分ける方法はないのでしょうか。

そんな要望にこのページで応えてみたいと思います。

≫振り分け処理の概要

単純な話ですが、以下のような処理でページを割り振ります。
  1. アクセスしてきた環境を調べる
  2. 環境に適したページへ割り振る
アクセスしてきた環境は、接続されるごとに調べなければいけないので動的な仕組み(CGI,SSI)が必要です。

割り振る方法はいくつかありますが、アクセスしてきたURLから別のURLにリダイレクト(ジャンプ)させる方法はなんとなくスマートに思えないので省略します。また、もともと使用していた index.html を index.cgi に変更する方法もファイル名変更がスマートに思えないので省略。URLもファイル名もさわらずに割り振る方法を紹介します。

≫SSIを使用します

SSI とは Server Side Include の略で、HTML の中に特殊なコマンドを記述して動的な対応をします。CGI よりも以前からある仕組みだそうです。複雑な処理をするなら SSI よりもページ全体を CGI 処理した方が良いかもしれませんが、今回のような処理には SSI が最適な仕組みであったりします。

まず、ご利用のサーバスペースで SSI が使用できるか確認してみましょう。SSI は便利な反面ヘタをすると重大なセキュリティホールを招く危険性(例えば、タグの使用や HTML のコメントアウトを避けていない HTML を書き出す掲示板 CGI など)があるため、レンタルスペースなどでは許可されていないことも多いです。

また、.htaccess ファイルによって 通常は実行できないように設定されている SSI を実行できるサーバもあったりします。いずれにせよ、SSI は通常 .shtml という拡張子の HTML ファイル内に記述することを推奨されているので、.html ファイルで SSI を実行するには .htaccess での設定が必要となります(稀にデフォルトで .html でも SSI 実行可能なサーバがあるかもしれませんが)。

≫具体的な仕組み

以下の様な処理体系を構築します。
  1. 今まで通りの index.html へアクセス
  2. index.html 内の SSI により pckt.cgi を呼び出し
  3. pckt.cgi の処理によりアクセス環境を判定
  4. pckt.cgi の処理により最適なページを読み込み出力
例えば、PC向け、iモード向け、J-SKY向けの3タイプの振り分けをする場合、用意するのは以下の様なファイルになります。
  • index.html
    今まで通りのものです。中身については後述。
  • .htaccess
    .html ファイルで SSI を実行できるように設定します。
  • pckt.cgi
    振り分け処理用の CGI ファイル。
  • pc.txt
    PCブラウザ向けの HTML ファイル(拡張子は.txt)
  • i.txt
    iモード向けの HTML ファイル(拡張子は.txt)
  • j.txt
    J-SKY 向けの HTML ファイル(拡張子は.txt)
設置構成は以下のようにします。


/public_html/──┼--- index.html [604]
                 │    .htaccess [604]
                 │
                 ┼---/cgi-bin/----┼-- pckt.cgi [705]
                      [705]             pc.txt [604]
                                        i.txt [604]
                                        j.txt [604]
*[ ]内はパーミション値


では、それぞれのファイルの中身です。

[ index.html ]
<!--#exec cmd="./cgi-bin/pckt.cgi"-->
たったのこれ一行です。SSI コマンドのみです。
この記述により、index.html がリクエストされると pckt.cgi が呼び出され実行されます。

[ .htaccess ]
Options +Includes AddType text/x-server-parsed-html .html
Options +Includes は SSI を有効にするための記述。AddType text/x-server-parsed-html .html は .html ファイルで SSI を有効にするための記述。元々 .htaccess がある場合は以上の記述を追加します。
通常、.htaccess は置かれているディレクトリ以下のディレクトリ全てで同じく有効になります。

[ pckt.cgi ]

#!/usr/bin/perl

# PC向けのファイルパスを指定
# (ファイルパスは全て index.html からの相対パス)
$file = './cgi-bin/pc.txt';

# 振り分け判定
if($ENV{'REMOTE_ADDR'} =~ /^210\.153\.84\./ || $ENV{'REMOTE_ADDR'} =~ /^210\.136\.161\./){
	$file = './cgi-bin/i.txt';
}else{
	$i = $ENV{'REMOTE_HOST'};
	if($i =~ /\.docomo\.ne\.jp/){
		$file = './cgi-bin/i.txt';
	}elsif($i =~ /\.jp-[ckqt]\.ne\.jp/){
		$file = './cgi-bin/j.txt';
	}
}

# ファイルの読み込みと出力
open (RD,"<$file");
while (<RD>){
	print $_;
}
close(RD);

exit(0);
一行目の #!/usr/bin/perl は Perlパスというもので、サーバによっては #!/usr/local/bin/perl だったりします。わからない場合は、サーバ管理者などに問い合わせてみましょう。ここがサーバ環境に合ってないと間違いなく動きません。

[ pc.txt ]
PC向けの HTML を記述します。
もともとの index.html の内容を記述します。

[ i.txt ]
iモード向けの CHTML を記述します。


[ j.txt ]
J-SKY向けの XHTML を記述します。


XX.txt ファイル内のアドレス指定を相対指定する場合は、index.html からの相対位置で指定します。つまり、XX.txt が設置されているのは、/cgi-bin/ ですが、index.html の位置にあるものとして相対指定します。

≫au とか PC向けでももっと細かく振り分けるには

ここでは、なるべくシンプルな構造で解説しましたが、実際には携帯端末でも au があったり、iモードでもバージョンによって使えるタグが違ったりします。また、PC向けのブラウザによっても種類によって表示が微妙に違ったりするので、それぞれにあわせてもっと多くの振り分けを行いたい場合があると思います。

そのような場合は、XX.txt を振り分ける数だけ増やし、pckt.cgi の振り分け部分を少し改良するだけで対応可能です。

pckt.cgi を改良するために簡単に解説しておきます。ここで記述されている以上の知識は検索エンジンなどでお調べ願います。
  • $file = './cgi-bin/pc.txt';
    $file という変数に ./cgi-bin/pc.txt を代入しています。./cgi-bin/pc.txt はindex.html からみた pc 向けの HTML が記述されているファイルパスです。
     
  • if( 条件 ){ 処理 }
    条件が真なら(成り立てば)、処理を実行します。
     
  • if( 条件 ){ 処理1 }else{ 処理2 }
    条件が真なら(成り立てば)、処理1を実行します。偽なら(成り立たなければ)、処理2を実行します。
     
  • if( 条件1 ){ 処理1 }elsif( 条件2 ){ 処理2 }
    条件1が真なら(成り立てば)、処理1を実行します。偽なら(成り立たなければ)、条件2を判断して真なら(成り立てば)、処理2を実行します。
     
  • $ENV{'REMOTE_ADDR'}
    $ENV{'hoge'} というのは環境変数と呼ばれるハッシュ変数で、コマンドが呼び出されるとサーバで自動的に設定されます。
     
    環境変数には以下の様なものもあります。
     
  • if($ENV{'REMOTE_ADDR'} =~ /^210\.153\.84\./){ 処理 }
    =~ /^210\.153\.84\./ というのは、正規表現によるマッチ判定をしています。$ENV{'REMOTE_ADDR'} が 210.153.84.XXX であれば真です。XXX のところは何がきてもOKです。この辺はちょっとややこしいので、わからない人は数字部分を変更するだけにとどめた方がいいかもしれません。
     
  • open (RD,"<$file");
    $file を読み込みますよという命令です。ここは変更するまでもないでしょうが。
     
  • while (<RD>){ 処理 }
    while( 条件 ){ 処理 } で、条件が真(成り立つ)のあいだ処理を繰り返します。<RD> のRD は、どういう意味かと言うと、ファイルハンドルと呼ばれるもので、open 命令にある RD と同じです。
    振り分け処理の場合、 while はさわる必要がないのでここでは以上の解説にとどめます。
     
  • close(RD);
    ファイルハンドル RD を閉じます。最新の Perlだとわざわざ閉じなくても勝手に閉じてくれるらしいんですが、念のため。マメに。
     
  • exit(0);
    処理を終了します。(0)は無くても exit; でもいいんですが、ここもマメに記述してみてます。
     
以上のような感じです。

≫さいごに

SSI を .html で実行できるようにすると、SSIの記述されていない .html でも SSI コマンドが含まれているかどうかサーバがいちいち判定するので、多少サーバ負荷が増えます。

相対パスの記述などは慣れるまで大変かもしれないですが、それほど難しいことではないと思いますので、頑張ってください。

あと、SSIの処理がダウンすると、ひとたまりもなく index.html が表示できなくなります。
そういう場合の対処として、ここでは、XX.txt として解説したファイルを XX.html としておいて、index.html が表示できない時は直接 XX.html を読んでもらう方法があります。
ただ、事前に XX.html を告知しなければいけないのと、直接読まれると、XX.html 内の相対パス指定がおかしなことになりますし、cgi-bin 内では.html ファイルを表示できないサーバもあるので、実用的ではないかもしれません。
ダウンしないことを祈りましょう(祈ってどうにかなるもんでもないですが(´ν`))

と、いうわけで、ひとまず、PC向けと、iモード、J-SKYを振り分けるだけなら、このページのまんまでOKのはずなので是非挑戦してみてください。


TOP > スクリプト制作メモ > パソコン(PC)向けページと携帯向けページの振り分け方法について
(C) bayashi.net