Apache mod_rewrite模組

2019-10-16 22:02:03

Apache mod_rewrite模組模組使用基於規則的重寫引擎(基於PCRE正規表示式解析器)來動態重寫請求的URL。預設情況下,mod_rewrite將URL對映到檔案系統路徑。但是,它也可用於將一個URL重定向到另一個URL,或呼叫內部代理提取。

mod_rewrite提供了一種靈活而強大的方法來使用無限數量的規則來操縱URL。每個規則都可以具有無限數量的附加規則條件,以用於根據伺服器變數,環境變數,HTTP檔頭或時間戳重寫URL。

mod_rewrite在完整的URL路徑上執行,包括path-info部分。可以在httpd.conf.htaccess中呼叫重寫規則。重寫規則生成的路徑可以包括查詢字串,也可以導致內部子處理,外部請求重定向或內部代理吞吐量。

註:更多詳細資訊,討論和範例,在詳細的mod_rewrite文件中提供。

紀錄檔記錄

mod_rewrite提供了在trace1trace8紀錄檔級別的詳細紀錄檔記錄。可以使用LogLevel指令專門為mod_rewrite設定紀錄檔級別:最多級別偵錯,不記錄任何操作,而trace8表示幾乎所有操作都被記錄。

範例:

LogLevel alert rewrite:trace3

要獲取特定於mod_rewrite的紀錄檔訊息,可通過grep管道紀錄檔檔案:

tail -f error_log|fgrep '[rewrite:'

RewriteBase指令

RewriteBase指令指定用於替換相對路徑的每個目錄(htaccess)RewriteRule指令的URL字首。

除非滿足以下任何條件,否則在每個目錄(htaccess)上下文中使用替換中的相對路徑時,此指令是必需的:

  • 原始請求和替換位於DocumentRoot下面(而不是通過其他方式,例如Alias可到達)。
  • 包含RewriteRule的目錄的檔案系統路徑(以相對替換為字尾)也可用作伺服器上的URL路徑。
  • 在Apache HTTP Server 2.4.16及更高版本中,當通過Aliasmod_userdir對映請求時,可以省略此偽指令。

在下面的範例中,RewriteBase是必要的,以避免重寫到http://example.com/opt/myapp-1.2.3/welcome.html,因為資源不是相對於文件根目錄。這種錯誤組態通常會導致伺服器在文件根目錄下查詢opt目錄。

DocumentRoot "/var/www/example.com"
AliasMatch "^/myapp" "/opt/myapp-1.2.3"
<Directory "/opt/myapp-1.2.3">
    RewriteEngine On
    RewriteBase "/myapp/"
    RewriteRule "^index\.html$"  "welcome.html"
</Directory>

RewriteCond指令

RewriteCond指令定義規則條件。一個或多個RewriteCond可以在RewriteRule指令之前。然後,僅當URI的當前狀態與其模式匹配,並且滿足這些條件時,才使用以下規則。

TestString是一個字串,除了純文字之外還可以包含以下擴充套件構造:

  • RewriteRule反向參照:這些是$N(0 <= N <= 9)形式的反向參照。$1$9可以從RewriteRule存取模式的分組部分(括號中),RewriteRule受當前RewriteCond條件集的約束。$0提供對該模式匹配的整個字串的存取。
  • RewriteCond反向參照:這些是%N形式的反向參照(0 <= N <= 9)。%1%9提供對模式的分組部分(同樣,在括號中)的存取,從當前條件集中的最後匹配的RewriteCond%0提供對該模式匹配的整個字串的存取。
  • RewriteMap擴充套件:這些是${mapname:key | default}形式的擴充套件。
  • 伺服器變數:這些是%{NAME_OF_VARIABLE}形式的變數。

如果TestString具有特殊值expr,則CondPattern將被視為ap_expr。如果沒有給出novary標誌,表示式中參照的HTTP頭將被新增到Vary頭。

範例:

RewriteCond /var/www/%{REQUEST_URI} !-f
RewriteRule ^(.+) /other/archive/$1 [R]

在下面的範例中,-strmatch用於將REFERER與站點主機名進行比較,以阻止不需要的熱連結。

RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule "^/images" "-" [F]

使用此選項可將規則條件與本地OR組合,而不是隱式AND。典型例子:

RewriteCond "%{REMOTE_HOST}"  "^host1"  [OR]
RewriteCond "%{REMOTE_HOST}"  "^host2"  [OR]
RewriteCond "%{REMOTE_HOST}"  "^host3"
RewriteRule ...some special stuff for any of these hosts...

要根據請求的「User-Agent:」標題重寫網站的主頁,可以使用以下內容:

RewriteCond  "%{HTTP_USER_AGENT}"  "(iPhone|Blackberry|Android)"
RewriteRule  "^/$"                 "/homepage.mobile.html"  [L]

RewriteRule  "^/$"                 "/homepage.std.html"     [L]

RewriteEngine指令

RewriteEngine指令啟用或禁用執行時重寫引擎。如果設定為off,則此模組根本不進行執行時處理。它甚至不更新SCRIPT_URx環境變數。

使用此偽指令禁用特定上下文中的規則,而不是注釋掉所有RewriteRule偽指令。

請注意,虛擬主機不會繼承重寫組態。這意味著您需要為要在其中使用重寫規則的每個虛擬主機指定RewriteEngine on指令。

如果在沒有將RewriteEngine設定為on的上下文中定義了prg型別的RewriteMap指令,則它們不會在伺服器初始化期間啟動。

RewriteMap指令

RewriteMap指令定義了一個重寫對映,它可以通過對映函式在規則替換字串中使用,以通過鍵查詢插入/替換欄位。此查詢的來源可以是各種型別。

MapName是對映的名稱,將用於通過以下構造之一為重寫規則的替換字串指定對映函式:

${ MapName : LookupKey }
${ MapName : LookupKey | DefaultValue }

當發生這樣的構造時,查詢對映MapName並查詢鍵LookupKey。如果找到鍵,則map-function構造將由SubstValue替換。如果未找到鍵,則如果未指定DefaultValue,則將其替換為DefaultValue或空字串。空值的行為就像鍵不存在一樣,因此無法區分空值鍵和缺少鍵。

例如,可以將RewriteMap定義為:

RewriteMap examplemap "txt:/path/to/file/map.txt"

然後,可以在RewriteRule中使用此對映,如下所示:

RewriteRule "^/ex/(.*)" "${examplemap:$1}"