Mod-Rewrite

Apache 不匹配重寫的 URL 作為正常文件

  • June 15, 2019

我已經設置了一個.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

bar.php顯然,如果重寫的 URL 指向它,Apache 不會將其視為正常文件。www.example.com/foo/bar.php按預期工作。

任何想法為什麼?

編輯#1:

為了澄清,這是文件結構:

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

編輯#2:

我正在執行 Apache 2.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 到與測試/htdocs/foo/bar.php不匹配的RewriteCond本地路徑!-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指令將按原樣更新為最後一個RewriteRuleie 的輸出。http://www.example.com/foo/bar.php. 在這個階段它不會重新映射到文件系統。(除非您指定了相對路徑替換,在這種情況下,目錄前綴將被添加 - 這似乎是您在日誌中看到的 - 但這與問題中的指令不對應。)

因此,上述條件確實是“匹配的”——“絕對 URL”不可能作為文件系統中的文件存在。

然後你會得到一個損壞的302“重寫”到doh.php. 請求在內部被重寫doh.php,但是HTTP狀態從之前的“重定向”設置為302,但是沒有Location標頭,所以沒有外部重定向。(雖然你似乎暗示有一個“重定向”到doh.php?)

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

為了觸發外部重定向(考慮到後面的重寫),您需要包含L( last) 標誌以停止目前輪的處理。

您還應該明確並包含R標誌。此處隱含 302 重定向,因為您已在RewriteRule.

例如:

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

在旁邊:

這些規則不會重定向www.example.com/foo

請注意,如果您請求/foo沒有尾部斜杠並且/foo是物理目錄,則 mod_dir 將首先隱式 301 重定向到/foo/,以便通過附加尾部斜杠來“修復”URL。

引用自:https://serverfault.com/questions/971530