web-dev-qa-db-ja.com

RewriteBaseの機能と使用方法

いくつかの.htaccessトリック。 RewriteBaseディレクティブに遭遇しましたが、正しく機能させることができませんでした。

このディレクティブが具体的に何をし、どのように使用するのか疑問に思います。 StackOverflowおよびApacheドキュメントでRewriteBaseについていくつかの議論がありましたが、それでも、私の質問に対する明確な答えを得ることができませんでした。

誰かがRewriteBaseを使用できるシンプルだが効果的な例を見せてくれませんか?

47
Chong Lip Phang

Htaccessファイルでは、mod_rewriteは<Directory>または<Location>コンテナと同様に機能します。 RewriteBase は、相対パスベースを提供するために使用されます。

たとえば、次のフォルダー構造があるとします。

root
 |-- subdir1
 |-- subdir2
       |-- subsubdir

以下にアクセスできます:

  • http://example.com/(ルート)
  • http://example.com/subdir1(subdir1)
  • http://example.com/subdir2(subdir2)
  • http://example.com/subdir2/subsubdir(サブサブディレクトリ)

RewriteRuleを介して送信されるURIは、ディレクトリに相対的です。あなたが持っている場合:

RewriteRule ^(.*)$ - 

ルートで、リクエストが/a/b/c/dの場合、キャプチャされたURI($1)はa/b/c/dです。ただし、ルールがsubdir2にあり、リクエストが/subdir2/e/f/gである場合、キャプチャされたURIはe/f/gです。ルールがsubsubdirにあり、リクエストが/subdir2/subsubdir/x/y/zである場合、キャプチャされたURIはx/y/zです。ルールが含まれるディレクトリには、その部分がURIから取り除かれています。書き換えベースはこれに影響を与えません。これは単にディレクトリごとの動作です。

書き換えベースが行うことは、URLパスベースを提供します(notファイルパスベース)ルールのターゲット内の相対パス。このルールがあるとしましょう:

RewriteRule ^foo$ bar.php [L]

bar.phpは相対パスです:

RewriteRule ^foo$ /bar.php [L]

ここで、/bar.phpは絶対パスです。絶対パスは、always(上記のディレクトリ構造内の)「ルート」になります。つまり、ルールが「root」、「subdir1」、「subsubdir」などにある場合、/bar.phpパスは常にhttp://example.com/bar.phpにマッピングされます。

ただし、相対パスを使用するもう1つのルールは、ルールが含まれているディレクトリに基づいています。

RewriteRule ^foo$ bar.php [L]

「ルート」にあり、http://example.com/fooにアクセスすると、http://example.com/bar.phpが提供されます。ただし、そのルールが「subdir1」ディレクトリにあり、http://example.com/subdir1/fooに移動すると、http://example.com/subdir1/bar.phpが提供されます。等。これは時々機能し、時には機能しません。ドキュメントにあるように、相対パスではrequiredになっているはずですが、ほとんどの場合そうです働く。リダイレクトする場合を除き(Rフラグを使用するか、ルールのターゲットにhttp://Hostがあるために暗黙的に)。それはこのルールを意味します:

RewriteRule ^foo$ bar.php [L,R]

「subdir2」ディレクトリにあり、http://example.com/subdir2/fooに移動すると、mod_rewriteは相対パスをURLパスではなくファイルパスと間違え、Rフラグがあるため、 http://example.com/var/www/localhost/htdocs/subdir1のようなものにリダイレクトされることになります。これは明らかにあなたが望むものではありません。

これがRewriteBaseの出番です。ディレクティブはmod_rewriteにすべての相対パスの先頭に追加するものを指示します。だから私が持っている場合:

RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]

そのルールは「subsubdir」にあり、http://example.com/subdir2/subsubdir/fooに移動すると、実際にhttp://example.com/blah/bar.phpが処理されます。 「bar.php」がベースの最後に追加されます。実際には、同じディレクトリコンテナまたはhtaccessファイルに複数のベースを置くことはできないため、この例は通常は望みのものではありません。

ほとんどの場合、次のように使用されます。

RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]

これらのルールは「subdir1」ディレクトリにあり、

RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]

「subsubdir」ディレクトリにあります。

これにより、ルールを移植可能にすることができるため、ルールを任意のディレクトリにドロップでき、ルールの束ではなくベースを変更するだけで済みます。たとえば、次の場合:

RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...

http://example.com/subdir1/fooに行くとhttp://example.com/subdir1/bar.phpなどになります。これらのファイルとルールをすべて「subsubdir」ディレクトリに移動することにしたとします。 /subdir1/のすべてのインスタンスを/subdir2/subsubdir/に変更する代わりに、ベースを作成することもできます。

RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...

そして、それらのファイルとルールを別のディレクトリに移動する必要があるときは、ベースを変更するだけです:

RewriteBase /subdir2/subsubdir/

以上です。

92
Jon Lin

RewriteBaseは、mod_rewriteは、RewriteRuleの結果に自動的にプレフィックスを付けます。 .htaccessのコンテキスト内での書き換えは、その.htaccessファイルを含むディレクトリに対して行われます。 RewriteRuleの直接の結果は、まだ.htaccessファイルを含むディレクトリに対して相対的ですが、mod_rewriteはこの結果を調整し、代わりにドキュメントルートに対して相対的にします。 RewriteBaseを使用すると、この最後の手順を変更して、RewriteRuleの結果の直前に追加される任意のbaseパスを提供できます。 、ドキュメントルートの代わりに。

私にとって、RewriteBaseディレクティブを理解するキーポイントは、mod_rewriteがRewriteBaseを結果に適用することに気づいたときです引数ではなく、RewriteRulesの。

.htaccessファイルのコンテキスト内でのRewriteRuleの通常の処理は次のようになります。

  1. .htaccessファイルを含むディレクトリに関連する要求されたパスを生成します。たとえば、URIが https://www.example.com/one/two/three で、.htaccessファイルのパスが/doc_root/one/.htaccess、生成されるパスは/two/three
  2. RewriteRulesは、上からの相対パスを書き換えます。
  3. 上記の結果の書き換えられたパスの前に、.htaccessファイルへのフルファイルシステムパスをプレフィックス
  4. 上記の書き換えられたパスの先頭からドキュメントルートへのパスを削除します。

このプロセスにより、ドキュメントルートに対する相対パスが書き換えられます。

RewriteBaseディレクティブがある場合、ステップ1、2、および3は同じままで、ステップ4のみが変更されます。ドキュメントルートの代わりに、.htaccessファイルを含むディレクトリへのファイルシステムパスが削除されます。次に、RewriteBaseが付加されます。

例:

  • リクエスト-https://example.com/one/two/three/file.txt
  • ドキュメントルート-/var/doc_root
  • Htaccessの場所-/var/doc_root/one/.htaccess
  • RewriteBase-/var/other_location/

HtaccessファイルにRewriteBaseがない場合、これは次のように処理されます。

  1. Htaccessに関連する要求されたパスの一部を取得する-/two/three/file.txt
  2. 書き換えを行う-/four/rewritten.txt
  3. .htaccessファイルへのパスを先頭に追加-/var/do_root/one/four/rewritten.txt
  4. ドキュメントルートを削除-one/four/rewritten.txt

.htaccessファイルのRewriteBaseを使用すると、これは次のように処理されます。

  1. Htaccessに関連する要求されたパスの一部を取得する-/two/three/file.txt
  2. 書き換えを行う-/four/rewritten.txt
  3. RewriteBaseの前に追加-/var/other_location/four/rewritten.txt
1
Dom