2012-12-26 61 views
1

有規則:爲什麼mod_rewrite的過程中,規則[L]標誌後

RewriteEngine on 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule (.+) dir/index.php?$1 [L] 
RewriteRule dir/index\.php.* - [F] 

爲什麼最後的規則處理,併爲所有請求返回紫禁城?

我需要,如果沒有找到文件或目錄,那麼不應該處理下一個規則。

下一個例子是不是爲我工作,以及:

RewriteEngine on 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule .? - [S=1] 
RewriteRule dir/index\.php.* - [F] 
RewriteRule (.+) dir/index.php?$1 

它仍然會返回禁止所有請求。

+0

我想我有一個答案。但最後一行應該怎麼做? –

+2

[L]僅適用於當前的迭代。重寫的url,被認爲是相同的重寫過程,導致禁止重寫。 Apache繼續應用規則,直到url不再更改。 – Gerben

+0

@Salman A,最後一個字符串假設限制直接訪問UFL處理程序。 – Mansoor

回答

2

爲什麼最後的規則會被處理,並且它會針對所有請求返回Forbidden?

當URL foobar請求:

  • 的兩個條件(第2行,3)匹配
  • 模式相匹配,則結果URL變得dir/index.php?foobar(第4行)
  • [L]標誌導致重寫停止 - 它不會阻止Apache從重寫的URL進入另一個URL,因爲它已更改(請參見下文)。

隨着dir/index.php作爲輸入URL:

  • 條件不匹配,因爲文件(第2行)存在
  • 跳轉到第5行
  • 模式匹配,因此禁止錯誤

當目錄或文件名更改時,Apache必須重新評估各種配置部分(例如DirectoryFiles)和.htaccess文件的「重寫」路徑。這就是爲什麼Apache可能會執行另一次迭代,即使前一個由[L]標誌結束。

最後一個字符串假設限制直接訪問UFL處理程序。 直接訪問是指通過如下鏈接請求文件:domain.com/dir/index。PHP

我認爲加上另一個條件線5之前應該工作:

RewriteCond %{THE_REQUEST} dir/index\.php\x20HTTP/\d\.\d$ 
RewriteRule . - [F] 

THE_REQUEST服務器變量包含不應用任何重寫由瀏覽器所發送的請求。這對於檢測瀏覽器請求的最初的頁面可能是有用的。

THE_REQUEST

由瀏覽器發送到服務器的完整的HTTP請求線(例如, 「GET /index.html HTTP/1.1」)。這不包括瀏覽器發送的任何附加 標頭。與以下大多數其他變量不同,此值尚未經過轉換(解碼) 。

+0

非常感謝@Salman A,它現在可以工作! :) – Mansoor

+1

最後一個字符串可能會更短:RewriteRule。 - [F] – Mansoor

+0

並添加[NC]標誌會導致某人可以編寫diR/index.php並獲得對該文件的訪問:) – Mansoor

0

我不完全確定你的意思是「下一個規則」。

但是,如果您不希望在請求不存在的文件時執行某些規則,那麼使用以下結構可能會有所幫助。使用[R]用於重定向代替[L]可能與還要返回禁止所有請求的問題幫助(在下面的代碼段被從Apache RewriteRule Flags Page複製)

# Is the request for a non-existent file? 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
# If so, skip these two RewriteRules 
RewriteRule .? - [S=2] 

    RewriteRule (.*\.gif) images.php?$1 
    RewriteRule (.*\.html) docs.php?$1 

並且還。

+0

寫在那裏:[L]標誌導致mod_rewrite停止處理規則集。在大多數情況下,這意味着如果規則匹配,則不會處理更多規則。但他們是! – Mansoor