RewriteBase directive mod_rewrite專用於重定向步驟,在所有其他處理過程中被忽略。與文檔所述相反,通常沒有必要,因爲(就像你的情況一樣),將URL映射到DOCUMENT_ROOT
以外的文件系統中的子目錄是相當常見的。
那麼,指令是幹什麼的?當您在使用.htaccess文件時在每個目錄上下文中評估您的規則時,URL在Apache的請求處理鏈中很晚才傳遞給mod_rewrite。這意味着URL可能已經被部分轉換爲文件系統路徑,所以/目錄/子目錄/文件中的路徑實際上可能已經通過網絡服務器經由/位置/子目錄/文件被訪問。
這似乎不是一個問題,但事實上,/位置/片斷已成爲mod_rewrite的一個問題。爲了理解爲什麼,你必須知道mod_rewrite是如何使每個目錄上下文重寫成爲可能的。
當您在.htaccess文件中執行重寫時,mod_rewrite會將修改後的請求作爲內部重定向重新映射到Apache,就像它是一個URL一樣。這是有問題的,因爲請求路徑可能不是合適的URL傳遞。舉例來說,如果請求結束了在/目錄/子目錄/文件(我們假設是DOCUMENT_ROOT
外),我們可能有這樣的規則/directory/.htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php
這將檢查/子目錄/文件,確定它不是一個實際的文件,並將其重寫爲index.php。此時,必須將新的URL返回給Apache以進行內部重定向以完成重寫。由於它沒有參考點,它最終發送整個路徑—,即它發送/directory/index.php。這不是你想要的,因爲訪問這個位置的URL實際上是/location/index.php。這就是RewriteBase用武之地。通過在.htaccess文件中指定
RewriteBase /location/
,目錄前綴/目錄/會被交換出去/位置/因爲這改寫後的處理的一部分,導致內部重定向到預期的URL /location/index.php。
這也與外部重定向有關。如果您嘗試僅使用[R]
標誌進行外部重定向,並且該路徑沒有前導斜槓,則整個目錄將以上述方式發送回客戶端,除非它被替換爲RewriteBase。
雖然這些點都不會與您的情況相關,所以您應該沒有指定RewriteBase即可。
%{DOCUMENT_ROOT}
變量只是Apache內部DOCUMENT_ROOT
變量的值,它在您的服務器/虛擬主機配置中設置。它始終對應於/要求解決的目錄。 -f
和-d
檢查需要完整的文件系統路徑,這就是爲什麼當使用它們時%{DOCUMENT_ROOT}
需要預先添加到相對路徑。
但是,爲了解決當前請求的路徑,mod_rewrite爲您提供了%{REQUEST_FILENAME}
變量。舉例來說,假設.htaccess文件住在你的/安全子目錄,您可以修改您的規則設置如下:
RewriteEngine On
# Force PHP extension if not a directory
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule^- [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]
看看這個http://serverfault.com/questions/720085/htaccess的死因無限循環活服務器上,但是,作品上,本地主機 – sammyukavi 2015-09-04 12:04:50