Rewrite命令

Rewirte主要的功能就是實現URL的跳轉和隱藏真實地址,基於Perl語言的正則表達式規範。平時幫助我們實現擬靜態,擬目錄,域名跳轉,防止盜鏈等。本文將針對mod_rewrite和URL匹配的技術細節,以及RewriteCond與RewriteRule 指令格式進行探討。

內部處理,API,規則集處理,

內部處理

Rewirte模組內部處理
Rewirte模組的內部處理極為複雜,但是為了使一般用戶避免犯低級錯誤,也讓管理員能充分利用其功能,在此仍然做一下說明。

API

Rewirte模組API階段
首先,你必須了解Apache是分若干階段來處理HTTP請求的。Apache API對每個階段都提供了一個hook程式。mod_rewrite使用兩個hook程式:其一,從URL到檔案名稱的轉換hook(用在讀取HTTP請求之後、授權開始之前); 其二,修正hook(用在授權階段和讀取目錄級配置(.htaccess)之後、內容處理器激活之前)。
所以,Apache收到一個請求並且確定了回響主機(或虛擬主機)之後,重寫引擎即開始處理伺服器級配置中的所有mod_rewrite指令(此時處於從URL到檔案名稱轉換的階段),此階段完成後,最終的數據目錄便確定了。接下來進入修正程式段並觸發目錄級配置中的mod_rewrite指令。這兩個階段並不是涇渭分明的,但都實施了把URL重寫成新的URL或者檔案名稱。雖然API最初不是為此目的而設計的,但是現在它已經成為了API的一種用途。記住以下兩點,會有助於更好地理解:
1、雖然mod_rewrite可以將URL重寫為新的URL或檔案名稱,甚至將檔案名稱重寫為新的檔案名稱,但是之前的API只提供從URL到檔案名稱的hook。在Apache 2.0中,增加了兩個丟失的hook以使得處理過程更加清晰。不過這樣做並沒有給用戶帶來麻煩,用戶只需記住這樣一個事實:藉助從URL到檔案名稱的hook比最初API設計的目標功能更強大。
2、令人難以置信的是,mod_rewrite還提供了目錄級的URL操作(.htaccess檔案),而這些檔案必須在將URL轉換成檔案名稱之後才會被處理(這是必須的,因為.htaccess存在於檔案系統中)。換句話說,根據API階段,這時再處理任何URL操作已經太晚了。為了解決這個”雞和蛋”的問題,mod_rewrite使用了一個小技巧:在進行一個目錄級的URL/檔案名稱操作時,先把檔案名稱重寫回相應的URL(通常這個操作是不可行的,但是參考下面的RewriteBase指令就能明白它是怎么實現的了),然後,對這個新的URL建立一個新的內部的子請求,再重新開始API階段的執行。
另外,mod_rewrite盡力使這些複雜的操作對用戶透明。但仍須記住:伺服器級的URL操作速度快而且效率高,而目錄級的操作由於這個”雞和蛋”的問題速度較慢而且效率也低。但從另一個側面看,這卻是mod_rewrite得以為一般用戶提供(局部限制的)URL操作的唯一方法。

規則集處理

Rewirte模組規則集的處理
當mod_rewrite在這兩個API階段中開始執行時,它會讀取配置結構中配置好的 (或者是在服務啟動時建立的伺服器級的,或者是在遍歷目錄採集到的目錄級的)規則集,然後,啟動URL重寫引擎來處理(帶有一個或多個條件的)規則集。無論是伺服器級的還是目錄級的規則集,都是由同一個URL重寫引擎處理,只是最終結果處理不同而已。
規則集中規則的順序是很重要的,因為重寫引擎是按一種特殊的順序處理的:逐個遍歷每個規則(RewriteRule指令),如果出現一個匹配條件的規則,則可能回頭遍歷已有的規則條件(RewriteCond指令)。由於歷史的原因,條件規則是前置的,所以控制流程略顯冗長,細節見圖-1。
圖-1:重寫規則集中的控制流
可見,URL首先與每個規則的Pattern匹配,如果匹配失敗,mod_rewrite將立即終止此規則的處理,繼而處理下一個規則。如果匹配成功,mod_rewrite將尋找相應的規則條件,如果一個條件都沒有,則簡單地用Substitution構造的新值來替換URL,然後繼續處理其他規則;但是如果條件存在,則開始一個內部循環按其列出的順序逐個處理。對規則條件的處理有所不同:URL並不與模式進行匹配,而是首先通過擴展變數、反向引用、查找映射表等步驟建立一個TestString字元串,然後用它來與CondPattern匹配。如果匹配失敗,則整個條件集和對應的規則失敗;如果匹配成功,則執行下一個規則直到所有條件執行完畢。如果所有條件得以匹配,則以Substitution替換URL,並且繼續處理。

相關詞條

熱門詞條

聯絡我們