<-
Apache > HTTP 伺服器 > 文件 > 版本 2.4 > 重寫

Apache mod_rewrite 技術詳細資料

可用語言:  en  |  fr 

本文檔討論了 mod_rewrite 和網址配對的一些技術細節。

Support Apache!

另請參閱

top

API 階段

Apache HTTP 伺服器以幾個階段來處理請求。在這些階段中,可能會呼叫一個或多個模組來處理請求生命週期的那一部分。階段包括 URL 到檔案名稱的轉換、驗證、授權、內容和記錄等項目(這並非詳盡的清單)。

mod_rewrite 在其中的兩個階段(或通常稱為「掛勾」)中作用,以影響網址的重寫方式。

首先,它使用 URL 到檔案名稱的轉換掛勾,這會在讀取 HTTP 請求後,但在任何授權開始前發生。其次,它使用修正掛勾,在授權階段之後,並且在讀取每個目錄設定檔(.htaccess 檔)後,但在呼叫內容處理程式之前。

因此,在請求進來並已確定對應的伺服器或虛擬主機後,重寫引擎會開始處理出現在每個伺服器設定中的所有 mod_rewrite 指令(即在主伺服器設定檔和 <Virtualhost> 區段中)。這在 URL 到檔案名稱的階段會發生。

經過幾個步驟後,一旦找到最後的資料目錄,就會套用每個目錄設定指令(.htaccess 檔和 <Directory> 區塊)。這在修正階段發生。

在這些情況中的每一個情況裡,mod_rewrite 會將 REQUEST_URI 重寫成一個新 URL 或一個檔案名稱。

在每個目錄的內容中(即在 .htaccess 檔和 Directory 區塊內),這些規則會在 URL 已轉換為檔案名稱後才會套用。因此,mod_rewrite 最初會針對 RewriteRule 指令比對的 URL 路徑,是已轉換的檔案名稱的完整檔案系統路徑,並從前面移除目前目錄的路徑(包含尾斜線)。

以下為範例說明:如果規則在 /var/www/foo/.htaccess 中,且正在處理對 /foo/bar/baz 的要求,則類似 ^bar/baz$ 的表示法將相符。

如果在每個目錄的環境中進行取代,則會以新的 URL 發布新的內部次要要求,這會重新啟動要求階段的處理。如果取代是一個相對路徑,則 RewriteBase 指示會決定附加在取代開頭的 URL 路徑前置詞。在每個目錄的環境中,必須注意建立規則,這些規則最後(在未來某些「回合」的每個目錄重新寫入處理中)不會執行取代,以避免迴圈。(請參閱 RewriteLooping 以進一步討論此問題。)

由於在每個目錄的環境中進一步操作 URL,因此您需要特別注意在不同環境中設計不同的重新寫入規則。特別是,請記住,當您的重新寫入規則看到時,將會從 URL 中去除開頭的目錄路徑。對於以下的範例,請思考更多進一步的說明。

規則的位置 規則
VirtualHost 區段 RewriteRule "^/images/(.+)\.jpg" "/images/$1.gif"
文件根目錄中的 .htaccess 檔案 RewriteRule "^images/(.+)\.jpg" "images/$1.gif"
images 目錄中的 .htaccess 檔案 RewriteRule "^(.+)\.jpg" "$1.gif"

若要深入了解 mod_rewrite 如何在不同的環境中操作 URL,您應該諮詢在重新寫入期間建立的 日誌條目

top

規則集處理

現在,當 mod_rewrite 在這兩個 API 階段中觸發時,它會從其設定結構中讀取設定好的規則集(這個結構本身是在啟動時針對每個伺服器環境建立,或是針對 Apache 核心的每個目錄中所走的目錄而建立)。接著,重新寫入 URL 的引擎會以包含的規則集啟動(一個或多個規則與其條件)。重新寫入 URL 的引擎本身的操作方式對於兩個設定環境而言完全相同。只有最終的結果處理方式不同。

規則集中的規則順序很重要,因為重新寫入的引擎會以特別(且不太顯而易見)的順序來處理這些規則。規則如下:重新寫入的引擎會逐一迴圈瀏覽規則集的規則 (RewriteRule 指示),當某個特定規則相符時,它會選擇性地迴圈瀏覽現有的對應條件 (RewriteCond 指示)。基於歷史原因,條件會先提供,因此控制流程會稍微冗長。更多詳細資料請參閱圖 1。

Flow of RewriteRule and RewriteCond matching
圖 1:透過重新寫入規則集的控制流程

首先,URL 會根據各項規則的模式進行比對。如果比對失敗,mod_rewrite 會立即停止處理該項規則,並繼續處理下一項規則。如果模式比對成功,mod_rewrite 會尋找對應的規則條件(找出在設定檔中 RewriteRule 上方緊接的 RewriteCond 指示)。如果找不到任何規則,它便會用字串取代來取代 URL,並繼續進行規則圈回。如果出現條件,則它會開始一個內部圈回,來處理按順序列出的條件。對於條件,其中的邏輯不同:我們並未針對目前的 URL 比對某項模式。取而代之的是,我們會先擴充變數、反向參考、對應查詢等來建立字串測試字串,然後再嘗試用條件模式與之比對。如果模式比對失敗,整組條件和對應的規則便會失敗。如果模式比對成功,則會處理下一個條件,直到沒有更多條件為止。如果所有條件都比對成功,則會繼續處理,並將 URL 用取代取代。

可用語言:  en  |  fr 

top

意見

注意事項
這不是問與答區段。在此處發表的評論應針對改進文件或伺服器的建議,如果這些評論已實行或被視為無效或與主題無關,我們的管理員可能會移除這些評論。有關如何管理 Apache HTTP 伺服器方面的問題應導向我們的 IRC 頻道 #httpd(在 Libera.chat),或傳送至我們的郵寄清單