連載
» 2010年06月21日 00時00分 公開

いまさら聞けない!? Web系開発者のためのサーバ知識(4):ApacheとWebアプリケーションの連携 (1/3)

ブラウザから渡されたURLの解釈は、Webサーバで行うべきか、Webアプリ(フレームワーク)側で行うべきか。設計上の選択に幅があることをWeb開発者としても理解しておきたいものです(編集部)

[竹下肯己,株式会社 qnote]

スッキリしたURLの表現を使う

 Webアプリケーションでは、ブラウザ側で指定するURLは特別な意味を持っています。

 それは、ニュース記事などのように単にコンテンツの所在を示すだけでなく、そのWebアプリケーションで扱うサブメニューやパラメータまでをURLの一部として表現し、サーバ側にこれらを伝える役割を果たすことがあるためです。

 例えば、以下のようにパラメータでコンテンツのIDやアプリケーションが取るべきアクション、その際に指定するモードを並べたURLが考えられます。

http://サーバ名/index.php?action=test&mode=edit&id=123 ....

 このようなURLでWebアプリケーションを実行してももちろん構わないのですが、パラメータが増えるにしたがって分かりづらくなりますし、SEO対策的にも好ましくありません。上記を、例えば以下のようなURLで表現できたらどうでしょうか。

http://サーバ名/test/edit/123

 かなりスッキリしますね。Apacheの拡張機能を利用すると、ブラウザ側で指定されたURLを、サーバ側で任意のURLに書き換えて、リダイレクトさせることができます。このとき、静的ページのようなURLから、旧来の動的なURLへと書き換えるようにしてあげれば、見た目は上記のようなスッキリしたURLで、Webアプリケーションを動作させることができるわけです。また、あえてApache側では複雑な書き換えを行わず、Webアプリケーション側でパラメータを抽出するようにしてあげると、さらに柔軟な解釈も可能となります。

拡張機能「mod_rewrite」でURLを書き換える

 Apacheの拡張機能であるmod_rewriteを使うと、アクセスされたURLを書き換えてリダイレクトさせることができます。

 mod_rewriteはApacheの拡張モジュールとして提供されています。当連載で解説した手順でApacheをインストールしていれば、mod_rewriteのモジュールは既に組み込まれているはずです。ソースからインストールした場合にはインストール先(/usr/local/apache2 など)の下のmodulesというディレクトリに、RPMからインストールした場合には /etc/httpd/modules というディレクトリに、「mod_rewrite.so」というファイルが存在するはずです。これがmod_rewriteのモジュールです。

 次にhttpd.confを見てみると、「LoadModule rewrite_module modules/mod_rewrite.so」という設定があると思います。これは文字通り、先ほどの拡張モジュールをロードするための設定です。Apacheの機能の多くは、このようにモジュールで提供され、必要に応じてロードして利用する仕組みとなっています。

 mod_rewriteによるURLの書き換えはディレクトリごとに設定するため、前回の記事でご紹介した「<Directory "ディレクトリパス"> 〜 </Directory>」の中に記述するか、または.htaccessに記述します。今回は、より手軽に編集できる.htaccessを利用する方法で試してみます。

 .htaccessを利用する場合、対象ディレクトリに対して、AllowOverrideにて設定の上書きが許可されている必要があります(AllowOverrideについては前回の記事を参照してください)。mod_rewriteを設定するには、少なくともFileInfoが上書き可能になっている必要がありますが、今回は「AllowOverride ALL」ですべて上書き可能としました。

 また、同じく.htaccessでmod_rewriteを設定するには、Optionsで少なくともFollowSymLinksが有効になっている必要があります(Optionsについても前回の記事で紹介しました)。

 今回はApacheをRPMでインストールした環境で、デフォルトのドキュメントルート(/var/www/html)に.htaccessを設置してmod_rewriteによるリダイレクトを試してみることにします。httpd.conf内の、ドキュメントルートに対する設定例を下記に示しておきます(httpd.confを編集したらApacheを再起動してください)。

<Directory "/var/www/html">
    Options FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

mod_rewriteの基本

 では実際にリダイレクトの設定をしてみましょう。ドキュメントルート(/var/www/html)の下に.htaccessを作成し、以下のように記述してみてください(ドキュメントルートにindex.htmlがあることを前提とします)。

RewriteEngine On
RewriteBase /
RewriteRule ^.*$ index.html

 そして、http://サーバ名/xxx/ooo というURLでアクセスしてみてください(もちろん、ドキュメントルートには「xxx/ooo」というディレクトリやファイルは存在しないものとします)。

 ご想像通り、ドキュメントルートのindex.htmlが表示されたはずです。.htaccessの設定がなければ、これはもちろん404(Not Found)のエラーとなります。

 上記は、mod_rewriteのもっとも単純な設定例です。設定項目を順番に見ていきましょう。

  • RewriteEngine
    mod_rewrite の機能の On/Off を指定します。

  • RewriteBase
    URL書き換えの基準となるディレクトリです。この設定項目は省略可能で、省略した場合には実際のURLの階層が適用されます。例えば、/var/www/html/test/にmod_rewriteを設定した場合、デフォルトのRewriteBaseは“/test/”ということになります。これはつまり、/test/abc.htmlにアクセスがあったら“abc.html”に対してマッチング(後述)が行われ、リダイレクト先として“xyz.html”が指定されていたら/test/xyz.htmlにリダイレクトされるということです。Apacheで別名(alias)などを利用していると、実階層とURLが一致しない場合もあるため、この設定が用意されています。

  • RewriteRule
    具体的なURL書き換えのルールはRewriteRuleに記述します。書式は、

    RewriteRule 正規表現 書き換えURL フラグ(省略可)

    のようになっています。アクセスされた実際のURLが、1番目のパラメータである正規表現にマッチした場合、2番目のパラメータであるURLに書き換えられます。先ほどの設定例では、正規表現ですべてのURLにマッチさせ、これをindex.htmlに書き換えていました。

 RewriteRuleの詳細についてはApacheのWebサイトにあるドキュメントを参照してください。

RewriteRule適用の追加条件

 RewriteRuleでは、URLが正規表現にマッチしたときに書き換えを行いますが、URL以外の条件(例えばアクセス元のIPアドレスなど)で書き換えするかどうかを決定したい場合もあります。このようなときは、RewriteCondという設定項目を利用して、ある条件に一致する場合のみRewriteRuleを適用するといった設定も可能です。

 RewriteCond の書式は、

RewriteCond 判定対象 判定条件

 となります。判定対象には、ログ設定のところでも解説した環境変数などが利用できます。判定条件には正規表現などを指定します。例えばアクセス元IPアドレスによって、RewriteRuleを適用するかどうか判断したい場合は、以下のように記述します。

RewriteCond %{Remote_Addr} 192.168.
RewriteRule ^wan.html$ lan.html

 このように、対象となるRewriteRuleの前に記述します。上記では、“wan.html”にアクセスがあり、かつそのアクセス元IPアドレスが 192.168.〜だったら、“lan.html”へとリダイレクトしています。

 判定条件の部分はやや拡張された正規表現となっており、例えば以下のような表現も可能です。

・パターンに一致しない場合をつかまえたい(先頭に "!" を付加)

RewriteCond  %{HTTP_USER_AGENT}  !^Mozilla.*

・数値や文字列の大小比較(先頭に ">" や "<" や "=" を付加)

RewriteCond %{TIME_YEAR} >2000
RewriteCond %{TIME_YEAR} <2010

 なお、RewriteCondを複数指定した場合には、条件はANDで評価されます(すべての条件が満たされたときにRewriteされる)。条件をORで評価させたい場合は、RewriteCondを“[OR]”でつなぎます。

RewriteCond %{Remote_Addr} 192.168. [OR]
RewriteCond %{Remote_Addr} 10.

 RewriteCondの詳細についてはApacheのWebサイトにあるドキュメントを参照してください。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。