web-dev-qa-db-ja.com

.htaccessからの重複URLを引き起こさないApacheのキャッチオール書き換えルール

エイリアスのように機能するApacheのキャッチオール書き換えルールを作成できますが、エイリアスはできないのに.htaccessファイルに実装できます。

例として、ドキュメントルートが次のような階層であると仮定します。

/.htaccess
/test/
/test/.htaccess
/test/file

ルートを.htaccessに含めることで、テストフォルダへのすべてのリクエストを「エイリアス」できます。

RewriteEngine On
RewriteRule ^(.*)$ /test/$1 [L]

そして、2番目の.htaccessには次のものが含まれます。

RewriteEngine On

これはうまく機能し、通常は必要なすべてです。問題は1つだけです。複数の有効なURLが作成されます。これで、/file/test/fileの両方でファイルにアクセスできます。

通常、これは問題ではありませんが、/test/testというファイルを追加すると、偽のエイリアスが完全に機能しなくなるため、問題が発生します。サブフォルダーに独自の複雑な.htaccessがある場合、大きな頭痛の種になる可能性があります。

元のURLがまだ機能していない状態で、.htaccessからエイリアスを偽造する方法はありますか? (サブフォルダーのRewriteCondは、すでに書き換えられているかどうかを確認しますか?)

3
J V

...しかし、/test/testというファイルを追加すると、偽のエイリアスが完全に機能しなくなるため、問題が発生します。

はい、サブディレクトリの2番目の.htaccessファイルはURLの書き換えを防ぎます(mod-rewriteはデフォルトで継承されないため)。これを回避するには、ドキュメントルートに.htaccessファイルを1つ入れて、まだ書き換えられていないすべてのリクエストを書き換えます。例えば:

RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /test/$1 [L]

REDIRECT_STATUS環境変数は、最初の要求では空であり、最初の正常な書き換え後に200(OK)に設定されます。

ただし、サブディレクトリ内の.htaccessファイル(他のmod_rewriteディレクティブの場合)がまだneedである場合は、次のいずれかを行う必要があります。

  • サブディレクトリ.htaccessファイルでこれらのディレクティブを繰り返します。 (その場合、親の.htaccessファイルに上記のRewriteCondディレクティブは厳密には必要ありません。)

  • または、mod_rewrite継承を有効にします。しかし、Apache2.2では苦労すると思います。おそらく、Apache2.4でのみ使用可能なRewriteOptions InheritBefore(サブディレクトリ.htaccessファイル内)のようなものが必要になります。

問題は1つだけです。複数の有効なURLが作成されます。

上記の方法では、すべてのリクエストが書き換えられるため、この問題も解決されます(これは、サーバー構成でのApache Aliasの動作に似ています)。


それ以外の場合は、ベースサブディレクトリに直接アクセスした場合にドキュメントルートに戻る正規のリダイレクトを実装できるように、ベースサブディレクトリが一意であることを確認する必要があります。例えば:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /unique-subdir
RewriteRule (.*) /$1 [R=301,L]

THE_REQUESTは、initial要求ヘッダーの最初の行を保持し、要求が書き換えられても変更されません。

1
MrWhite