RewriteRuleの定義を.htaccessに行った際、設定によって、ブラウザのURL欄が書き換わったり、換わらなかったりしたので、その辺の仕様を改めて調べた結果のメモです。
URL書き換えの基本
.htaccessでRewriteRuleを使用すると、指定されたURLを書き換える事が出来る。
例えば、下記のルールは、任意のURL指定に対しても、Yahooのホームページが表示されるようになる。
この書き換えルールは、.htaccessが存在するディレクトリ以下のURLに対して適用される。
RewriteRule ^.*$ http://www.yahoo.co.jp/ |
この際のアドレスバー表示は、http://www.yahoo.co.jp/になる。
これが以下のルールの場合、アドレスバーの表示は変更されない
RewriteRule ^.*$ lib/contoller.php |
結果として、ブラウザ側からするとURLのリライトが行われた事を検出できない。
これをforward(もしくはinternal redirect)と呼ぶ。
しかし、Rewrite後のURLをドメイン名付きで定義した場合は、redirect(もしくはexternal redirect)となる。
RewriteRule ^.*$ http://my.domain.com/lib/contoller.php |
アドレスバー表示も、書き換え後のURLになる。
このときクライアント側のブラウザはリダイレクトが行われた事を検出できる。
実際には一旦Status=302:Foundでレスポンスが返され、Locationヘッダにhttp://my.domain.com/lib/contoller.phpが指定される(firebugで確認)。その後ブラウザは、302レスポンスコード受信時の仕様に従い、改めてhttp://my.domain.com/lib/contoller.phpへリクエストを投げる事になる。
この振る舞いは、たとえRewriteRuleに記載されているmy.domain.comが、最初のリクエストがあったサーバと同じであっても行われる(apacheからすると、my.domain.comが自分である事を確認できないため??)。
また、URLにドメインを明記しなくても、external redirectを明示する事は可能になっている。
下記の例のように、変更後URLの後ろにR=301と表記する事で、明示的に301リダイレクトを行わせる事が出来る。もちろんR=302とすれば、ステータスコード=302のときの振る舞いになるし、R=404でNotFoundにさせることも可能。
RewriteRule ^.*$ http://my.domain.com/lib/contoller.php [R=301] |
その他のオプション
RewriteRule書き換え後のURLが、再度ルールにマッチするとき、無限ループに陥ってしまう。これを防ぐにはルールの末尾に[L]オプションを定義する。

Apacheクックブック 第2版 ―Webサーバ管理者のためのレシピ集

サーバ構築の実際がわかる Apache[実践]運用/管理 (Software Design plus)
関連記事
[…] http://nanoappli.com/blog/archives/3017 […]