2013-03-11 37 views
2

我想讓我的站點上的所有URL由單個腳本處理。所以我把在這樣的重寫規則:如何重寫到腳本並使用.htaccess重定向,同時避免無限循環

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule (.*) /myscript.php?p=$1 [L] 

但我不希望允許訪問我的劇本上實際包含在其中「myscript.php」的網址,所以我想重定向這些回主要站點:

Redirect 301 /myscript.php http://example.com/ 

的問題是,如果我把這兩方面的規則爲我的.htaccess文件它會導致一個無限循環。我如何讓他們同時工作?

我也想能夠重定向的東西,如:

/myscript.php?p=foo -> /foo 

回答

1

使用環境變量完全可以,但是,您不需要自己手動設置此環境變量。 Apache提供了可用於此目的的REDIRECT_STATUS環境變量

REDIRECT_STATUS在初始請求時爲空(或未設置)。它在第一次(成功)內部重寫時設置爲200。或者在發生錯誤時使用其他一些HTTP狀態代碼(404等)。

因此,而不是檢查REDIRECT_LOOP1,我們可以簡單地檢查REDIRECT_STATUS是空的,以確保我們所測試的初始請求,而不是重寫的請求。例如:

RewriteCond %{ENV:REDIRECT_STATUS} ^$ 
RewriteRule ^myscript\.php$/[R,L] 

(請注意,這只是REDIRECT_STATUS,有在請求開始沒有STATUS變量)。


RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_URI} !myscript\.php 
RewriteRule (.*) /test/myscript.php?p=$1 [L,E=LOOP:1] 

旁白:RewriteCond指令檢查REQUEST_URI在這裏沒有真正做任何事情。如果第一個條件是真的(即它不是文件),那麼這個條件也必須是真的。但是,可以通過包括第一個來優化。然後這將避免請求(包括重寫的請求)的文件檢查。例如:

RewriteCond %{REQUEST_URI} !^/test/myscript\.php 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule (.*) /test/myscript.php?p=$1 [L] 

或者,您可以包括這個規則而不是停止處理前的預檢查(異常)當請求myscript.php

RewriteRule ^test/myscript\.php$ - [L] 

但是,如果你這樣做,那麼上述規範重定向必須出現之前這些規則,否則它們將不會被處理。 (無論如何,首先將規範重定向放在首位通常是可取的。)

3

你可以在你的第二個規則設置爲可變

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_URI} !myscript\.php 
RewriteRule (.*) /myscript.php?p=$1 [L,E=LOOP:1] 

的環境和測試

RewriteCond %{ENV:REDIRECT_LOOP} !1 
RewriteRule ^myscript\.php$/[R,L] 

千萬不要使用301啓用測試,請參閱此答案Tips for debugging .htaccess rewrite rules LS。

+0

@StephenOstermiller這與另一個問題/答案類似。請參閱http://stackoverflow.com/a/15244599/1741542 – 2013-03-11 14:41:08

+0

+1好的.--- – 2013-03-11 16:39:18