rewriteモジュールでURLを書き換えろ!
rewriteモジュール
Apacheにはrewriteモジュールという大変便利なモジュールがある。こいつは、内部でURLを書き換えることができる。内部でURLを書き換えるって・・・、何ができるんよ。っていう人、こんなんできるんだよー。
- PHPやCGIで動的ページを作りたいけど、GoogleやYahooのサーチエンジンに登録されなくなるんだよ・・・
- 携帯でのアクセスは別ページにしたいけど、www.a.com/i/みたいにしたくない・・・
- 動的ページでページがまだ作成されてない時にCGIへ飛ばしたい・・・
- レンタルサーバで共有SSLがあるんだが、CGI、PHPはHTTPSで、それ以外はHTTPにしたいな・・・
- 特定のリファイラやロボットにはアクセスさせたくない
などなど、この他にもやり方次第でいろいろできちゃうんだよね。こんな便利なモジュールは是非使わないと。。。
前提条件
前提条件としては、もちろんApacheでrewriteモジュールが読み込まれて無いとアウト。確認してみよう。
/etc/apache/modules.conf
これはApache1.3なので、Apache2だとちょっと違うかも。以下の行があることを確認しよう。
LoadModule rewrite_module /usr/lib/apache/1.3/mod_rewrite.so
RewriteEngine
自作エラーページでも書いたが、httpd.conf内のディレクティブにも書けるが、.htaccess内でも書くことができる。今回は.htaccessで書こうと思う。
まずはじめに、rewriteモジュールの有効化を記載する。
RewriteEngine On
RewriteRule
RewriteRuleとは、ある条件に一致したURLを指定したURLに変換することである。rewriteモジュールのメインですな
RewriteRule [パターン] [変換URL] [オプション]
パターンでは正規表現の使用が可能。オプションでは以下の設定が可能だ。よく使うだろう物しか書いてないので、後で全部書きます・・・
オプション
| オプション | 内容 |
|---|---|
| [F] | URLをアクセス禁止にする。403のレスポンスコードを返す |
| [R] | リダイレクトする。302のレスポンスコードを返す |
| [L] | 判定を終了する。継続して次に行かない |
| [N] | URLを書き換え、新しく再度rewriteを繰り返す |
RewriteCond
RewriteCondとは環境変数やその他の条件を使用し判定をする。この条件にマッチした場合に、次のRewiteRuleへと判定される。
RewriteCound [対象] [条件] [オプション]
対象で使用できる環境変数
よく使うやつだけ、抜粋
| 項目 | 内容 |
|---|---|
| HTTP_HOST | サーバのホスト名 |
| HTTP_REFERER | リンク元のURL |
| HTTP_USER_AGENT | ブラウザの種類 |
| REMOTE_ADDR | クライアントのIPアドレス |
| REMOTE_HOST | クライアントのホスト名 |
| REQUEST_URI | リクエストURI |
| REQUEST_URI | リクエストURI |
他にもたくさんあるので、以下のperlスクリプトでも流して確認してみてください
#! /usr/bin/perl
print "Content-type: text/html\n\n";
print "<table border=1>\n";
for $key (sort(keys(%ENV))) {
print "<tr><th>$key</th><td>$ENV{$key}<td></tr>\n";
}
print "</table>\n";
exit;
条件
こんな条件が設定できます
| 条件 | 内容 |
|---|---|
| ! | 否定 |
| < | 比較。小なり |
| > | 比較。大なり |
| = | 比較。同じ |
| -d | ディレクトリが存在しているか |
| -f | ファイルが存在しているか |
| -s | ファイルが0バイトじゃないか |
オプション
オプションはこの2つ
| オプション | 内容 |
|---|---|
| [OR] | 次のRewriteCondをOR条件で続ける |
| [NC] | 条件で大文字・小文字を区別しない |
使用例
さっそく、使用例をいくつか。各自、環境に合わせて変更してくれ
動的ページのサーチエンジン対応
動的ページを作成したいが、URLに変数等が入りサーチエンジンに登録されにくいから対策したい。
「www.foge.com/make.cgi?id=abc」この様なURLを「www.foge.com/abc.html」とアクセスさせる。そして、内部で初めのURLに変換すればよい
RewriteEngine On RewriteRule ^(.*).html$ /make.cgi?id=$1 [L]
携帯電話対策
携帯電話を専用ページで飛ばしたい。この場合はHTTP_USER_AGENTで書くページに飛ばせばいいだろう。
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} DoCoMo [OR]
RewriteCond %{HTTP_USER_AGENT} J-PHONE [OR]
RewriteCond %{HTTP_USER_AGENT} UP\.Browser
RewriteRule ^/$ i/index.html [L]
動的作成ページ
動的ページなのだが、初回だけ作ってあとは静的ページとしてみせたい。一度に大量にページを作成して、FTPでアップロードしなければならないサイトなどで、こいつを使えばアクセスする度に作成され、以降は単純な静的ページになるのでパフォーマンスのアップも期待できる。これは、ファイルを有無を確認してなければ、CGIへ。みたいなのでOKだろう
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^contents/(.*)$ /cgi-bin/makepage.cgi?id=$1 [L]
共有SSL対策
自宅サーバでは問題ないかもしれないが、レンタルサーバで共有SSLというもが無料で公開されている物がる。こいつは、通常のHTTPなら独自ドメインなのだが、共有SSLの場合はレンタルサーバのURLになってしまう。www.レンタルサーバ.com/~独自ドメイン/といった感じだ。
これでもいいが、気に食わないので特定CGIだけ共有SSLにして、それ以外は独自ドメインでアクセスさせたい場合にこれを使う
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/~独自ドメイン/
RewriteCond %{REQUEST_URI} !^/~独自ドメイン/cgi-bin/
RewriteRule (.*).html$ http://独自ドメイン/$1.html [R] [L]
こいつは、URIが「~/独自ドメイン」で始まっていて、「/cgi-bin/」以外へのアクセスは、独自ドメインへリダイレクトさせている。