前のページで.htaccessでmod_rewriteモジュールを使って特定のIPアドレスからのアクセスを拒否する設定について、筆者の実験結果を含めて紹介しました。
この他にもmod_rewriteモジュールを使うとWebへのリクエストをリダイレクトしたり、書き換えたりすることができます。
これらを行う場合のRewriteCond/RewriteRuleディレクティブの書き方もせっかく調べたので備忘録としてまとめてみます。
【目次】
スマートフォンからのアクセスをリダイレクトする
スマートフォン(iPhone、Andorid、Windows Phone)からのアクセスを)別ディレクトリ配下の同じファイルへリダイレクトする方法を例にします。
※今回の例はカテゴリ配下のファイルへのアクセスのみ転送しています
この場合は、ブラウザがWebリクエストへ設定するUSER_AGENTを参照して、スマートフォンからのアクセスかどうかを判別します。
通常、スマートフォンのブラウザからのアクセスは、USER_AGENTに以下の文字列を入れています(PCからのリクエストには通常含まれていない)。
iPhone…【iPhone 】
Andoroid…【AndroidとMobile】
Windows Phone…【Windows Phone】
つまり、WebリクエストのUSER_AGENTにこれらの文字が含まれていれば、スマートフォンからのアクセスと判断することができます。
これを.htaccessへ記述すると以下のようになります。
RewriteEngine On RewriteBase / RewriteCond %{HTTP_USER_AGENT} (iPhone|Android.*Mobile|Windows.*Phone) [NC] RewriteRule ^([^/]+)/([^/]+)$ /sp/$1/$2 [R,L]
RewriteCondディレクティブの記述内容
(1)%{HTTP_USER_AGENT}
WebリクエストのUSER_AGENTを参照する
(2)(iPhone|Android.*Mobile|Windows.*Phone)
USER_AGENTの中に含まれている文字列の判定方法を正規表現で記述します。
今回は『iPhone』『AndroidとMobile』『WindowsとPhone』のいずれかが含まれているかどうかを判別しています。
※正規表現についての説明は割愛します
(3)[NC] (2)の文字列の判定を行う際、大文字と小文字の区別をしないで行うことを示します。
RewriteRuleディレクティブの記述内容
(1)^([^/]+)/([^/]+)$
転送元となるリクエストのパターンを記述します。
今回は全てのカテゴリ(ディレクトリ)配下の全てのファイルへのリクエストを一致させるように正規表現で表しています。
(2)/sp/$1/$2
(1)のパターンと一致した場合にspディレクトリ配下の転送元と同一ファイルへアクセスします。
$1や$2は(1)のパターンで(…)で囲んだ部分の前方参照です。(1)で使われたものがそのまま使用されます。
(3)[R,L]
オプションの指定です。
R…リダイレクトする
L…パターンに一致したらこのディレクティブ行を実行して終了する
動的ページを静的ページに見せる方法
PHPなどで動的に生成されるページを静的ページ(HTMLページ)に見せる方法です。
entry+数字+.htmlというページへのアクセスを、数字部分を引数にしてPHPスクリプトへ送るように書き換えます。
RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^entry([\d+])\.html article.php?fileid=$1 [L]
RewriteCondディレクティブの記述内容
(1)%{REQUEST_FILENAME}
Webリクエストのファイル名を参照します。
(2)!-f
‘!’は判定結果を逆転します。
‘-f’は参照したファイルが存在しているかを判定します。
今回は’!-f’となっているので、ファイルが存在しているかの判定を逆転し、ファイルが存在していないかを判定します。
ファイルが存在しない場合、次の行に続くRewriteRuleディレクティブを実行します。
RewriteRuleディレクティブの記述内容
RewriteRule ^entry([\d+])\.html article.php?fileid=$1 [L]
(1)^entry([\d+])\.html
転送元となるリクエストのパターンを記述します。
今回は全てのentryで始まり、その後に数字が続くHTMLファイルへのリクエストを一致させるようにを正規表現で表しています。
(2)article.php?fileid=$1
(1)のパターンと一致した場合にWebリクエストをarticle.phpへのリクエストへ書き換えます。この際、(1)の数字の部分を前方参照し、article.phpへの引数としています。
(3)[L]
オプションの指定です。
L…パターンに一致したらこのディレクティブ行を実行して終了する
その他の設定
RewriteCondで参照できる情報
種類 | 名前 |
---|---|
リクエストに設定される情報 | HTTP_USER_AGENT(ブラウザ情報) HTTP_REFERER(参照元ページURL) HTTP_COOKIE(クッキー) …など |
リクエストに関する情報 | REMOTE_ADDR(アクセス元IPアドレス) REMOTE_HOST(アクセス元ホスト名) REQUEST_METHOD(リクエストメソッド) QUERY_STRING(Webリクエストのパラメータ) …など |
その他 | REQUEST_URI(リクエストURI) REQUEST_FILENAME(リクエストファイル名) …など |
RewriteCondで判断できる特殊なパターン
パターン | 働き |
---|---|
! | 判定結果を逆転する |
-d | ディレクトリが存在しているか判定 |
-f | ファイルが存在しているか判定 |
-s | ファイルが存在していて、かつそのファイルが有限のサイズであるか判定 |
…など
RewriteCondに指定できるオプション
オプション | 意味 |
---|---|
[OR] | このRewriteCond行か次に続くRewriteCond行のいずれかが正しいならば、その後のRewriteRuleディレクティブを実行する([OR]が無い場合、次に続くRewriteCond行のいずれも正しい場合に、その後のRewriteRuleディレクティブを実行する) |
[NC] | 判定する際、大文字・小文字の区別を行わない |
RewriteRuleに指定できるオプション
オプション | 意味 |
---|---|
[R] | "302 Moved Temporaily"の応答をクライアントへ返してリダイレクトする |
[L] | パターンと一致したらこのディレクティブを実行した後、以降のRewriteRuleディレクティブを実行せず終了する |
[NS] | 一時的なWebリクエストの場合のみパターンとの一致を評価し、サーバで発生した二次的なリクエストは判定を行わない |
[N] | 書き換えした後で、再度新たなリクエストとして最初から判定をやり直す |
[C] | 次のRewriteRule行とパターンの条件を結合して、いずれも合致する場合にパターン一致とする |
[F] | パターンに一致したURLへのアクセスを拒否する(403エラーが返る) |
[P] | PROXYモジュールを使用して、他のサーバにあるコンテンツを取得し自サーバからクライアントへ返す |
まとめ
この他に、404などのエラーページへ任意のページを指定したり、特定のディレクトリ配下をBasic認証にすることなども可能です。
細かいURLの書き換えなどができる.htaccessファイルですが、編集を間違えるとページがまったく表示できなくなってしまうこともあるので注意が必要です(500 Internal Server Errorが発生)。
すぐに元へ戻せるように正しく表示できていた.htaccessファイルのバックアップを準備しておきましょう。