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}"
