目次

apache :: Rewrite(mod_rewrite)

特殊なパターン(第二引数)

! 文字列の前につけることで、否定を表現
< 文字列比較
> 文字列比較
= 文字列比較 
-d 指定したディレクトリが存在すれば true
-f 指定したファイルが存在すれば true
-s ファイルが存在し、サイズが0でなければ true
-F アクセス可能な有効なパスを指している場合に 
     true (内部サブリクエストを用いてcheckされる)
-U アクセス可能な有効なURLとなっている場合に 
     true (内部サブリクエストを用いてcheckされる)

オプション機能(第三引数)

第三引数説明
[C]chain 次のRewriteRuleと条件を結合する(置換禁止文字列”-“を用いて複数の条件をANDで複合適用する場合に用いる)
[E]environment E=VAR:VAL 環境変数のセット。VAR という名前の環境変数の値を VAL に するよう指示します
[F]forbidden(403) マッチしたURLへのアクセスを禁止する(クライアントには”403 Forbidden”のレスポンスが返される)
[G]gone(410) マッチしたURLは行方不明であることを伝える(クライアントには”410 Gone”のレスポンスが返される)
[L]last 条件にマッチした場合そこで判定を終了する(以下に続くRewriteRuleを評価しない)
[N]next 書き換えが済んだURLを新たなリクエストとして書き換え処理を再度最初のルールから繰り返す
[P]proxy PROXYモジュールを使用して他のサーバー(URL)にあるコンテンツを取得しその内容をクライントに返す
[R]redirect “302 Moved Temporaily”のレスポンスを返しクライアントをリダイレクトする。[R=301] と書けば、”301 Moved Permanently”に変更することもできる
[S]skip 現在のルールがマッチしたら、次の'数字'番目のルールをスキップするよう指示します。これを使って、擬似的に if-then-else 構造を作ることができます
[NC]no case 大文字小文字を区別しない
[NE]no escape 書き換え結果に対して通常行なわれるURLエスケープルールを適用しないようにします。出力の中にパーセント文字を 使うことができます
[NS]no subrequest 一次的なURLリクエストの場合のみ条件を評価(サーバー内部で発せられるサブリクエストの場合は判定をスキップする)
[OR]or 条件をorでつなぐ(背反する and は暗黙であるため、何も書かなければ and として扱われる)
[PT]pass through mod_alias と mod_rewrite の同時使用時などで使用する
[QSA]query string append 置換文字列の中でマッチしたものを書き換えるのではなく、そこにクエリー文字列部分を追加するように書き換えエンジンに強制します。書き換えルールを通してクエリー文字列に何かデータを追加したい場合にこのフラグを使います

オプション機能は組み合わせて使用することもできる。
例)[R=301,L,NS]

参照可能なサーバ変数

HTTP_USER_AGENT
HTTP_REFERER
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_ACCEPT
DOCUMENT_ROOT
SERVER_ADMIN
SERVER_NAME
SERVER_ADDR
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
REMOTE_ADDR
REMOTE_HOST
REMOTE_USER
REMOTE_IDENT
REQUEST_METHOD
SCRIPT_FILENAME
PATH_INFO
QUERY_STRING
AUTH_TYPE
TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME
ルール内ではエスケープして %{HTTP_USER_AGENT} と書く。

ユーザエージェントで振り分ける (1)

ユーザエージェント が UP, KDDI で始まらなければ、http://example.com へリダイレクト

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} !^(UP|KDDI)
RewriteRule ^.*$ http://example.com [R=301,L,NS]

ユーザエージェントで振り分ける (2)

キャリア毎にリダイレクト先を定義する。
複数のUAを記述する場合、[OR] を使ってソースコードを読みやすくする事ができる。

# DoCoMo
RewriteCond    %{HTTP_USER_AGENT}    ^DoCoMo
RewriteRule    ^.*$ http://example.com/d/ [R=301,L,NS]

# au
RewriteCond    %{HTTP_USER_AGENT}    ^KDDI [OR]
RewriteCond    %{HTTP_USER_AGENT}    UP\.Browser
RewriteRule    ^.*$ http://example.com/a/ [R=301,L,NS]

# SoftBank
RewriteCond    %{HTTP_USER_AGENT}    ^J-PHONE [OR]
RewriteCond    %{HTTP_USER_AGENT}    ^Vodafone [OR]
RewriteCond    %{HTTP_USER_AGENT}    ^SoftBank [OR]
RewriteCond    %{HTTP_USER_AGENT}    ^MOT-
RewriteRule    ^.*$ http://example.com/s/ [R=301,L,NS]

※. 一部のSoftBank端末で、UP.Browser を採用している機種が存在するので、このままでは誤作動します。

ユーザエージェントで振り分ける (3)

PCとケータイの振り分け

前提:

# /pc 配下のアクセスで無く、かつ UA がケータイでない => /pc へリダイレクト
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/pc
RewriteCond %{HTTP_USER_AGENT} !^(DoCoMo|UP|KDDI|SoftBank|Vodafone|J-PHONE|MOT-) [NC]
RewriteRule ^.*$ /pc [L]

# /pc 配下のアクセスであり、かつ UA がケータイである => / へリダイレクト
RewriteCond %{REQUEST_URI} ^/pc
RewriteCond %{HTTP_USER_AGENT} ^(DoCoMo|UP|KDDI|SoftBank|Vodafone|J-PHONE|MOT-) [NC]
RewriteRule ^.*$ / [L]

※. この設定を適用するときはHTML内のリンクを「絶対パス」で記述する事を推奨する。
理由は、内部ではURL書き換えが行われているが、ブラウザのURL欄に変化は無いので、リンク先に不整合が生じるからである。
[NG] <a href=“path/to/hoge.html”>
[OK] <a href=”/path/to/hoge.html”>

メンテナンス画面

RewriteEngine on
RewriteCond %{REQUEST_URI} !_mainte\.html
# 指定IPを除外
RewriteCond %{REMOTE_ADDR} !^192\.168\.0\.11$
RewriteCond %{REMOTE_ADDR} !^192\.168\.0\.12$
RewriteRule ^.*$ _mainte.html [L]
下記はもっと親切。
mod_rewrite (.htaccess) で簡単メンテナンスモード

クールURI (SEO対策)

RewriteEngine on
RewriteRule ^hoge/([0-9]+)$ hoge/fuga.php?id=$1 [L]

404 not found

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /404.php [L]
※ .htaccess の末行に書く。
※ 必ず「^.*$」とする。「^$」ではダメ。

RewriteMap

クリック数をカウントする場合にとても便利。

メリット

設定の仕方

httpd.conf と rewrite_map.txt(ファイル名は何でもよい) に設定を書く。

httpd.conf

<VirtualHost *:80>
    ServerName      example.com
    RewriteEngine   On
    RewriteMap      url_map  txt:/path/to/rewrite_map.txt
    RewriteRule     ^/(.+)   ${rewrite_map:$1|http://default.example.com/}  [NE,R,L]
</VirtualHost>

※. 「http://default.example.com/」は、rewrite_map.txt でマッチしなかった時のリダイレクト先URL

/path/to/rewrite_map.txt

フォーマット

リダイレクト元文字列 空白 リダイレクト先URL

dest1 http://dest1.example.com/
dest2 http://dest2.example.com/

挙動

「rewrite_map.txt」のマッピングに従ってリダイレクトします

http://example.com/dest1 にアクセス ⇒ http://dest1.example.com/ へリダイレクト

http://example.com/dest2 にアクセス ⇒ http://dest2.example.com/ へリダイレクト

http://example.com/unknown にアクセス ⇒ http://default.example.com/ へリダイレクト
↑ マッチしない場合

クリックカウント(集計)はどうするか?

RewriteMap を設定したサーバ「example.com」の apacheアクセスログ に rewrite_map.txt で設定した [リダイレクト元文字列] が残ります。
クリックカウント(集計) は grep コマンド で数えます。

例)dest1 のクリック数をカウントする

% grep 'GET /dest1' /path/to/access_log.yyyymmdd -c

-c オプションでカウント


関連エントリー: