Apache

【Apache】 [RewriteRule] リライトでURLを書き換える方法と意味を理解する

ApacheでURLを書き換える[RewriteRule] リライトの基本的な使い方を紹介します。 また、RewriteEngine、FollowSymLinks、RewriteRule、RewriteBaseなどの意味と使い方を説明します。

この記事の目次
  1. [RewriteRule] を使うための準備
  2. [RewriteRule] の基本的な書き方の説明
  3. Substitutionで指定できるもの
  4. Flagsについて
  5. [RewriteRule] の具体的な書き方
  6. [RewriteRule] と[Redirect]の違い
  7. [RewriteRule] の挙動
  8. RewriteBaseで簡略化

ApacheでURLを書き換える[RewriteRule] リライトの基本的な使い方を紹介します。
また、RewriteEngine、FollowSymLinks、RewriteRule、RewriteBaseなどの意味と使い方を説明します。

RewriteRuleの書き方はRewriteRule パターン 置換先 [フラグ]の3つで、先頭にRewriteEngine Onが必要です。
たとえばRewriteRule ^old/(.*)$ /new/$1 [R=301,L]と書くと、/old/以下へのアクセスを/new/以下へ301リダイレクトします。
[R]を付けなければURLは変わらず、サーバー内部で別のファイルを返すだけ(内部リライト)になります。
条件をつけて書き換えたい場合は、RewriteRuleの直前にRewriteCondを置きます。
.htaccessそのものの置き方や有効化(AllowOverride)、RewriteRule以外のディレクティブは、親記事のApache .htaccessの書き方と使い方|AllowOverride・RewriteRuleを解説で扱っています。
この記事はその続きとして、RewriteRule1行の構文(Pattern・Substitution・flags)の意味に絞って説明します。

[RewriteRule] を使うための準備

RewriteRuleのコンテキストは、サーバー設定, バーチャルホスト, ディレクトリ,
.htaccessです。そのためどこでも使えます。
RewriteRuleを使うためには、以下の二点を必ず行う必要があります。

  • 「RewriteEngine On」として、RewriteRuleの前に呼び出す
  • 「Options FollowSymLinks」をディレクトリで記述する

基本的にApacheでは、Options FollowSymLinksは有効になっています。
.htaccessに書いたRewriteRuleが無視される場合は、httpd.conf側のAllowOverrideがNoneになっていることが多く、この設定の仕方は上の親記事を参照してください。

<Directory />
    Options Indexes FollowSymLinks
    AllowOverride None
</Directory>

上のような記述があればOKです。

スポンサーリンク

[RewriteRule] の基本的な書き方の説明

RewriteRule Pattern Substitution [flags]

Patternには、パスにマッチする条件を正規表現で書きます。
Substitutionには置換先を書きます。
Patternのパスは、.htaccessのある階層からの相対パス(先頭のスラッシュなし)で記載します。
Substitutionはドメイン以降のパスを書く必要があります。
Redirectディレクティブに似ていますが、正規表現が使えるぶん柔軟に使用できます。
flagsは省略でき、指定する場合は[ ]の中にカンマ区切りで書きます。

Patternで()で囲んだ部分は、Substitution側で$1、$2として参照できます。

# /post/123 → /post.php?id=123 (URLは変わらない)
RewriteRule ^post/([0-9]+)$ /post.php?id=$1 [L]

Substitutionで指定できるもの

・URL-path:
ドメイン以下のパスによる指定です。
一番最初のパスがルートディレクトリに存在しない場合にURL-pathとして認識します。
以下が例です。

RewriteRule some-folder/index.html /alias/new-file-name.html

・file-system path:
PC上のディレクトリ、またはファイルへの絶対パスです。
windowsの場合はCドライブなどからのフルパスを記載します。
このfile-system pathが使えるのは、サーバ設定ファイルかバーチャルホストになるため、.htaccessファイル内では使えません。
以下が例です。

RewriteRule some-folder/index.html /Applications/MAMP/logs

・Absolute URL:
http~の絶対URLです。
外部リンクなどです。
以下が例です。

RewriteRule some-folder/index.html https://news.yahoo.co.jp/

・- (dash) 書き換えしない(フラグのみ使用)
フラグのみ使用する際に使用します。
以下が例です。

RewriteRule some-folder/index.html - [F]

Flagsについて

[R=code]

上のように記述します。
Rとした場合はリダイレクトします。
R=301とすると301リダイレクトを行います。

[L] 処理を終了します。以降のRewriteRuleは実行しないという意味になります。
[F] 403エラー(閲覧禁止 Forbidden)を発生させて、ページを表示しないようにできます。
[NC] Patternの大文字小文字を区別しません。
[QSA] 元のURLのクエリ文字列(?以降)を、置換先のクエリに追加して引き継ぎます。
複数使いたい場合は、[R=301,L]などとカンマ区切りで記載します。

[L]は「このルールで終わり」という意味ですが、.htaccessの中では書き換え後のURLで再度.htaccessが評価されるため、同じルールに何度もマッチしてリダイレクトループになることがあります。
ループする場合は、Patternを書き換え後のURLにマッチしないように厳密にするか、RewriteCondで%{REQUEST_FILENAME} !-fのような条件をつけます。
Apache 2.4以降なら[L]の代わりに[END]を使うと、再評価そのものを止められます。

[RewriteRule] の具体的な書き方

.htaccessに以下を記述します。

# リライトエンジンをONに設定
RewriteEngine On
# RewriteRule Pattern Substitution [flags]
RewriteRule some-folder/index.html /alias/new-file-name.html

リライトエンジンをONに設定することで、RewriteRuleが使えるようになります。
Patternのパスを書くときは、現在の階層からの相対パスで記載します。
Substitutionはドメイン以降のパスを書く必要があります。
前方のPatternのところに渡ってくる文字列は、.htaccessが置いてあるところまでのパスは渡ってきません。

[RewriteRule] と[Redirect]の違い

[RewriteRule] はURLは変更されません。
[Redirect]はURLまで変更されます。

[RewriteRule]を使った場合は、クライアント側にリライトを要求するのではなく、Apacheのサーバーの中で擬似的にリダイレクト処理を行うためです。
そのためクライアント側で表示するURLはそのままになります。

このように、Apache内部で行うリダイレクトのことを、internal redirectといいます。

Apache内部で擬似的にリダイレクトされているので、ブラウザの検証ツールのnetworkタブでも確認することはできません。

RewriteRule some-folder/index.html /alias/new-file-name.html [R]

ただし、末尾に[R]と記載した場合は、通常のリダイレクト処理と同じようになります。
この場合は、Redirectと同じように、検証ツールからでも処理の内容を確認できます。

[RewriteRule] の挙動

RewriteEngine On
RewriteRule some-folder/img01.jpeg /alias/img01.png

上の場合、URLはjpegとなりますが、ダウンロードした場合、pngファイルとなります。
検証ツールのcontent typeで確認できます。

RewriteEngine On
RewriteRule some-folder/ /alias/another-folder/

上の場合、some-folderにアクセスすると、index.htmlでもsample.htmlでもどのファイルにアクセスしても、another-folderのindex.htmlが常に返されます。

RewriteBaseで簡略化

RewriteEngine On
RewriteBase /alias/
RewriteRule some-folder/ another-folder/

RewriteBaseを使うと、Substitutionの先頭の共通パスを省略して記述できます。
複数の共通したパスがある場合はRewriteBaseを使うと効率化できます。

書いたRewriteRuleが効いているか分からないときは、リライトのログの出力方法でログを出すと、どのPatternにマッチして何に書き換わったかを確認できます。
別フォルダの同名ファイルへ振り分ける実例はRewriteで別のフォルダの同じファイル名へリダイレクトさせる方法にまとめています。

スポンサーリンク