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
提供了在trace1
到trace8
日誌級別的詳細日誌記錄。可以使用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及更高版本中,當通過
Alias
或mod_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}"