Apache mod_rewrite模块

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

上一篇: Apache URL重写 下一篇: Apache认证和授权