什麼時候不要使用URL重寫

2019-10-16 22:02:15

本文件描述了關於mod_rewrite的最重要的概念之一 - 即何時避免使用它。

當發現其他替代方案缺乏時,mod_rewrite應被視為最後的手段。當有更簡單的替代方案時使用它會導致組態混亂,易碎且難以維護。了解其他替代方案是朝著mod_rewrite掌握邁出的非常重要的一步。

注意,這些範例中的許多範例在您的特定伺服器組態中不會保持不變,因此您必須了解它們,而不是僅僅將範例剪下並貼上到您的組態中。

mod_rewrite是正確工具的最常見情況是,當最佳解決方案需要存取伺服器組態檔案時,如果沒有該存取許可權。某些組態指令僅在伺服器組態檔案中可用。因此,如果您處於託管情況,只能使用.htaccess檔案,一些組態可能需要求助於mod_rewrite

下面我們來看看,在哪些情況下不要使用URL得寫。

簡單的重定向

mod_alias提供RedirectRedirectMatch指令,它們提供了將一個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執行此任務可能是合適的。這是因為,當在同一範圍記憶體在RedirectRewriteRule指令時,無論組態檔案中的外觀順序如何,RewriteRule指令都將首先執行。

http-to-https重定向的情況下,如果您無權存取主伺服器組態檔案,則必須使用RewriteRule,並且必須在.htaccess檔案中執行此任務。

URL別名

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