2013-10-06 120 views
1

如果我有重新寫入規則:爲什麼RewriteCond需要此規則才能正常工作?

RewriteRule ([^?]*) /script.php?path=$1 [L,QSA] 

它會返回一個500內部錯誤,除非我也具備的條件:

RewriteCond %{REQUEST_FILENAME} !-f 

這是爲什麼?我的印象是這些條件並沒有真正改變規則的運作方式,而只是規則的例外。

+2

查看你的apache錯誤日誌,看看實際的錯誤是什麼,但它很可能是一個無限進行的重定向循環。條件是需要確保重定向只發生如果它不是一個真正的文件(所以script.php不會重定向到自己) –

回答

2

-f測試,如果給定參數是一個文件,如果它存在(它可能是0字節大小)。你得到500內部服務器錯誤的原因是因爲重寫引擎遍歷所有規則,直到URI停止更改。因此,舉例來說,如果你有是這樣的:

RewriteRule ([^?]*) /script.php?path=$1 [L,QSA] 

和請求進來爲/foobar URI是 「foobar的」

  1. 「foobar的」 匹配([^?]*),URI被改寫爲「/腳本.PHP?路徑= foobar的」
  2. 重寫發動機循環
  3. 「的script.php」 匹配([^?]*),URI被改寫爲 「/script.php?path=script」
  4. 重寫發動機循環

現在,如果你加上一條:

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ([^?]*) /script.php?path=$1 [L,QSA] 

和請求進來爲/foobar URI是 「foobar的」

  1. 「foobar的」 不存在,!-f文件是真
  2. 「foobar」匹配([^?]*),URI被重寫爲「/script.php?path=foobar」
  3. 重寫引擎循環
  4. 「的script.php」 一個真實存在的文件,!-f是假
  5. 條件是假的,因此不適用規則。重寫停止後,得到的URI是「/script.php?path=foobar」
+0

感謝您逐步完成此過程。我沒有意識到它循環。所以如果我只想排除那個單一的腳本文件,我只是有一個測試該腳本的%{REQUEST_URI}的條件? – ChrisD

1

這是您的規則:任何東西,但?

RewriteRule ([^?]*) /script.php?path=$1 [L,QSA] 

這裏([^?]*)比賽0以上的長度。然後它將其重寫爲/script.php URI。生成的URI再次被注入進行評估。請注意,([^?]*)將再次匹配,因爲它的non-?中的0個或更多個和規則會再次應用。此循環繼續,直到mod_rewrite用完遞歸限制(默認值= 10)。

現在,當你有

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ([^?]*) /script.php?path=$1 [L,QSA] 

RewriteCond %{REQUEST_FILENAME} !-f手段申請下一RewriteRule如果要求不是一個有效的文件。

現在在第一次重寫目標URI之後/script.php是一個有效的文件,RewriteCond這次失敗,規則不再被應用。

PS:此匹配模式([^?]*)將始終與所有的URL模式,因爲REQUEST_URI不能包含?

你的規則是等價的:

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule^/script.php?path=$1 [L,QSA] 
+1

我的意圖是匹配所有uri模式,但我沒有意識到有這是一個簡短的手。謝謝。 – ChrisD

相關問題