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