Apache HTTP Server 2.4 版本
本文件補充 mod_rewrite
的 參考文件。它描述有關 mod_rewrite
最重要的觀念之一,即何時避免使用它。
當其他替代方案不可行時,mod_rewrite
應視為最後的選擇。在存在較簡易的替代方案時使用它,會導致令人困惑、脆弱且難以維護的設定檔。了解其他可用的替代方案,是精通 mod_rewrite
的重要步驟。
請注意,這些範例中的許多在您特定的伺服器設定檔中不會維持不變,因此了解它們而不是剪貼範例並貼到設定檔裡非常重要。
mod_rewrite
為正確工具的最常見情況是,當時最好的解決方案需要存取伺服器設定檔,而您沒有存取權限。某些設定檔指令僅在伺服器設定檔中可用。因此,如果您在主機環境中,僅能使用 .htaccess 檔案,則可能需要使用 mod_rewrite
。
mod_alias
提供 Redirect
和 RedirectMatch
指令,提供將一個 URL 重導到另一個 URL 的方式。這種將一個 URL 或類別的 URL 簡單地重新導向其他地方,應使用這些指令,而非 RewriteRule
。RedirectMatch
允許你在重新導向標準中包含正規運算式,提供使用 RewriteRule
的許多優點。
RewriteRule
的常見用法是重新導向一類的 URL。例如,必須將 /one
目錄中的所有 URL 重新導向到 http://one.example.com/
,或者可能必須將所有的 http
請求重新導向到 https
。
這些情況最好由 Redirect
指令處理。請記住 Redirect
保留路徑資訊。也就是說,對 URL /one
的重新導向也會重新導向其下的所有 URL,例如 /one/two.html
和 /one/three/four.html
。
若要將 /one
下的 URL 重新導向到 http://one.example.com
,請執行下列步驟
Redirect "/one/" "http://one.example.com/"
若要將一個主機名重新導向到另一個主機名,例如 example.com
重新導向到 www.example.com
,請參閱 標準主機名 範例。
若要將 http
URL 重新導向到 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 重新導向的情況中,如果你無法存取主伺服器組態檔,而且必須在 .htaccess
檔中執行此任務,使用 RewriteRule
是適當的。
Alias
指令提供從 URI 到目錄的對應 (通常是 DocumentRoot
以外的目錄)。儘管可以透過 mod_rewrite
來進行此對應,基於簡單性和效能考量,Alias
是優先選用的方法。
Alias "/cats" "/var/www/virtualhosts/felines/htdocs"
在以下情況下,使用 mod_rewrite
來執行此對應可能是適當的:如果你無法存取伺服器組態檔。Alias 只能在伺服器或虛擬主機的內容中使用,而不能在 .htaccess
檔中使用。
如果在你的伺服器上啟用 Options FollowSymLinks
,符號連結會是執行相同任務的另一種方式。
雖然可以用 mod_rewrite 來處理 虛擬主機,但這並非理想的方式。建立單獨的 <VirtualHost>
區塊幾乎總是較佳的方法。如果您有大量虛擬主機,請考慮使用 mod_vhost_alias
自動建立這些主機。
像 mod_macro
等模組也很適合動態建立大量虛擬主機。
如果您使用的是不允許您存取伺服器設定檔的託管服務,因此只能使用 .htaccess
檔案進行設定,那麼使用 mod_rewrite
來建立虛擬主機可能是可行的。
請參閱 使用 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/"
當作用範圍中有其他有效的 RewriteRule
時,您可能需要使用 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
。