web-dev-qa-db-ja.com

Apacheは書き換えられたURLを通常のファイルと一致しません

.htaccessを設定して、含まれているディレクトリ/htdocs/fooに対するリクエストをファイルbar.phpにリダイレクトします。

まず第一に:私はこれを一般的に達成する方法を知っていますが、私の制御できない理由で、.htaccessはURLが通常のファイルに解決されるかどうかを確認し、解決されない場合はリダイレクトします。

それほど複雑に聞こえませんが、私はこれを解決することはできません。 :[

これは私の.htaccessです:

RewriteRule ^$ http://www.example.com/foo/bar.php

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* doh.php

これらのルールは、www.example.com/foobar.phpにリダイレクトせず、代わりにdoh.phpにリダイレクトします。

error.logを確認しましたが、ファイルbar.phpが存在するのに、何らかの理由で書き換え条件が一致しています。

RewriteCond: input='http://www.example.com/foo/bar.php' pattern='!-f' => matched

どうやらApacheは、書き換えられたURLがそれを指している場合、bar.phpを通常のファイルとは見なしません。 www.example.com/foo/bar.phpは期待どおりに機能します。

なぜ何かアイデアはありますか?

編集#1:

明確にするために、これはファイル構造です:

/ (File system root)
|
+ htdocs (Document root)
  |
  + foo
    |
    + .htaccess
    + bar.php
    + doh.php

編集#2:

Apache2.4を実行しています。

解決策:

RewriteCondは、REQUEST_FILENAMEローカルパスが含まれていることを想定しています。 Lフラグがないため、RewriteRuleREQUEST_FILENAMEを明らかにローカルパスではないURLに設定するため、!-fのテストは一致します。

最終的に、LフラグをRewriteRuleにアタッチすると、目的の動作が生成されます。

RewriteRule ^$ http://www.example.com/foo/bar.php [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* doh.php

URLがhttp://www.example.com/foo/bar.phpに書き換えられた後、新しいプロセスループが開始され、書き換えられたURLがRewriteCond/htdocs/foo/bar.phpテストと一致しないローカルパス!-fに再マッピングされます。そして、/htdocs/foo/bar.phpが渡されます。 :)

1
Thorsten
RewriteCond: input='/htdocs/foo/bar.php' pattern='!-f' => matched

これが過度に例示されているかどうかはわかりませんが、「何か他のこと」が起こっていない限り、上記の指示を考えると、これは期待どおりではありません。

最初の(暗黙の)リダイレクトにLフラグがないため、処理はすぐに次のディレクティブに進みます。この時点で、ログに次のようなものが表示されると思います。

RewriteCond: input='http://www.example.com/foo/bar.php' pattern='!-f' => matched

最初のRewriteRuleの直後に、REQUEST_FILENAMEディレクティブがそのまま最後のRewriteRuleの出力に更新されます。 http://www.example.com/foo/bar.php。この段階では、ファイルシステムに再マップされません。 (相対パスを指定していない限りsubstitution、その場合、ディレクトリプレフィックスが先頭に追加されます-これはログに表示されているように見えます-しかし、それはのディレクティブに対応していません質問。)

したがって、上記の条件は実際に「一致」しています。「絶対URL」はファイルシステム上のファイルとして存在できない可能性があります。

次に、破損 302「書き換え」をdoh.phpに取得します。リクエストは内部的に書き換えられました to doh.phpですが、HTTPステータスは以前の「リダイレクト」から302に設定されていますが、Locationヘッダーがないため、外部リダイレクト。 (あなたはdoh.phpへの「リダイレクト」があることを暗示しているように見えますが?)

RewriteRule ^$ http://www.example.com/foo/bar.php

外部リダイレクトをトリガーするには(後で書き換えた場合)、Llast)フラグを含めて、現在の処理ラウンドを停止する必要があります。

また、明示的で、Rフラグを含める必要があります。 RewriteRuleにスキームとホスト名を明示的に含めているため、ここでは302リダイレクトが暗示されています。

例えば:

RewriteRule ^$ http://www.example.com/foo/bar.php [R,L]

脇:

これらのルールはwww.example.com/fooをリダイレクトしません

末尾にスラッシュを付けずに/fooをリクエストし、/fooが物理ディレクトリである場合、mod_dirは最初に暗黙的に/foo/にリダイレクトし、URLを追加してURLを「修正」することに注意してください。末尾のスラッシュ。

1
MrWhite