ブラウザから渡されたURLの解釈は、Webサーバで行うべきか、Webアプリ(フレームワーク)側で行うべきか。設計上の選択に幅があることをWeb開発者としても理解しておきたいものです(編集部)
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アプリケーション側でパラメータを抽出するようにしてあげると、さらに柔軟な解釈も可能となります。
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>
では実際にリダイレクトの設定をしてみましょう。ドキュメントルート(/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のもっとも単純な設定例です。設定項目を順番に見ていきましょう。
RewriteRuleの詳細についてはApacheのWebサイトにあるドキュメントを参照してください。
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サイトにあるドキュメントを参照してください。
Copyright © ITmedia, Inc. All Rights Reserved.