本文件描述了關於mod_rewrite
的最重要的概念之一 - 即何時避免使用它。
當發現其他替代方案缺乏時,mod_rewrite
應被視為最後的手段。當有更簡單的替代方案時使用它會導致組態混亂,易碎且難以維護。了解其他替代方案是朝著mod_rewrite
掌握邁出的非常重要的一步。
注意,這些範例中的許多範例在您的特定伺服器組態中不會保持不變,因此您必須了解它們,而不是僅僅將範例剪下並貼上到您的組態中。
mod_rewrite
是正確工具的最常見情況是,當最佳解決方案需要存取伺服器組態檔案時,如果沒有該存取許可權。某些組態指令僅在伺服器組態檔案中可用。因此,如果您處於託管情況,只能使用.htaccess
檔案,一些組態可能需要求助於mod_rewrite
。
下面我們來看看,在哪些情況下不要使用URL得寫。
mod_alias
提供Redirect
和RedirectMatch
指令,它們提供了將一個URL重定向到另一個URL的方法。這種簡單的方式將一個URL或一類URL重定向到其他地方,應該使用這些指令而不是RewriteRule
來完成。RedirectMatch
用於在重定向標準中包含正規表示式,從而提供使用RewriteRule
的許多好處。
RewriteRule
的一個常見用途是重定向整個URL類。例如,/one
目錄中的所有URL都必須重定向到http://one.example.com/
,或者所有http請求都必須重定向到https。
Redirect
指令可以更好地處理這些情況。請記住,重定向會保留路徑資訊。也就是說,URL /one
的重定向也會重定向其下的所有網址,例如/one/two.html
和/one/three/four.html
。
要將/one
下的網址重定向到http://one.example.com
,請執行以下操作:
Redirect "/one/" "http://one.example.com/"
要將一個主機名重定向到另一個主機名,例如example.com
重定向www.example.com
,請參閱Canonical Hostnames組態。
要將http網址重定向到https,請執行以下操作:
<VirtualHost *:80>
ServerName www.example.com
Redirect "/" "https://www.example.com/"
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
如果在同一範圍內有其他RewriteRule
指令,則使用RewriteRule
執行此任務可能是合適的。這是因為,當在同一範圍記憶體在Redirect
和RewriteRule
指令時,無論組態檔案中的外觀順序如何,RewriteRule
指令都將首先執行。
在http-to-https
重定向的情況下,如果您無權存取主伺服器組態檔案,則必須使用RewriteRule
,並且必須在.htaccess
檔案中執行此任務。
Alias指令提供從URI到目錄的對映 - 通常是DocumentRoot
之外的目錄。儘管可以使用mod_rewrite
執行此對映,但出於簡單性和效能的原因,Alias是首選方法。
範例:
Alias "/cats" "/var/www/virtualhosts/felines/htdocs"
當您無權存取伺服器組態檔案時,可能需要使用mod_rewrite
執行此對映。別名只能在伺服器或虛擬主機上下文中使用,而不能在.htaccess
檔案中使用。
如果在伺服器上啟用了Options FollowSymLinks
,那麼符號連結將是實現相同目標的另一種方式。
儘管可以使用mod_rewrite
處理虛擬主機,但它很少是正確的方法。建立單獨的<VirtualHost>
塊幾乎總是正確的方法。如果擁有大量虛擬主機,請考慮使用mod_vhost_alias
自動建立這些主機。
mod_macro
之類的模組對於動態建立大量虛擬主機也很有用。
如果您使用的托管服務無法存取伺服器組態檔案,則使用mod_rewrite
建立虛擬主機可能是合適的,因此只能使用.htaccess
檔案進行組態。
有關如何實現此目的的更多詳細資訊,請參閱具有mod_rewrite
文件的虛擬主機,如果它仍然是正確的方法。
RewriteRule
提供[P]
標誌以通過mod_proxy
傳遞重寫的URI。
RewriteRule "^/?images(.*)" "http://imageserver.local/images$1" [P]
但是,在許多情況下,當不需要實際的模式匹配時,如上例所示,ProxyPass
指令是更好的選擇。這裡的範例可以呈現為:
ProxyPass "/images/" "http://imageserver.local/images/"
無論使用RewriteRule
還是ProxyPass
,仍然需要使用ProxyPassReverse
指令來捕獲從後端伺服器發出的重定向:
ProxyPassReverse "/images/" "http://imageserver.local/images/"
當在同一範圍內有其他RewriteRules
生效時,可能需要使用RewriteRule
,因為RewriteRule
通常會在ProxyPass
之前生效,因此可能會搶佔您要完成的任務。
mod_rewrite
經常用於根據特定環境變數或請求檔頭的存在與否來執行特定操作。使用<If>
可以更有效地完成此操作。
例如,考慮使用RewriteRule
強制規範主機名的常見場景,例如www.example.com
而不是example.com
。這可以使用<If>
指令完成,如下所示:
<If "req('Host') != 'www.example.com'">
Redirect "/" "http://www.example.com/"
</If>
此技術可用於基於任何請求檔頭,響應檔頭或環境變數採取操作,在許多常見方案中用來替換mod_rewrite
。