.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/foo
をbar.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
フラグがないため、RewriteRule
はREQUEST_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
が渡されます。 :)
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
外部リダイレクトをトリガーするには(後で書き換えた場合)、L
(last
)フラグを含めて、現在の処理ラウンドを停止する必要があります。
また、明示的で、R
フラグを含める必要があります。 RewriteRule
にスキームとホスト名を明示的に含めているため、ここでは302リダイレクトが暗示されています。
例えば:
RewriteRule ^$ http://www.example.com/foo/bar.php [R,L]
脇:
これらのルールは
www.example.com/foo
をリダイレクトしません
末尾にスラッシュを付けずに/foo
をリクエストし、/foo
が物理ディレクトリである場合、mod_dirは最初に暗黙的に/foo/
にリダイレクトし、URLを追加してURLを「修正」することに注意してください。末尾のスラッシュ。