本文补充了mod_rewrite
参考。它描述了使用mod_rewrite
所必需的基本概念。其他文件更详细,但这个文档应该有助于初学者弄湿Apache中的重写。
Apache URL重写介绍
Apache模块mod_rewrite
是一个非常强大和复杂的模块,它提供了一种进行URL操作的方法。有了它,您几乎可以进行所需的所有类型的URL重写。但是它有点复杂,并且可能对初学者来说是令人生畏的。
本文试图提供足够的背景知识,以便理解后面的内容,而不是盲目地复制。
请记住,许多常见的URL操作任务不需要mod_rewrite
的全部功能和复杂性。有关简单任务,请参阅mod_alias
以及有关将URL映射到文件系统的文档。
最后,在继续之前,请确保使用LogLevel
指令将mod_rewrite
的日志级别配置为其中一个跟踪级别。虽然这可以提供大量的信息,但它在调试mod_rewrite
配置问题时是必不可少的,因为它会告诉您每个规则的处理方式。
正则表达式
mod_rewrite
使用Perl兼容的正则表达式词汇表。在本文档中,我们不会尝试提供正则表达式的详细参考。推荐由Jeffrey Friedl撰写的PCRE手册页,Perl正则表达式手册页和精通正则表达式。
正则表达式词汇
以下是最小构建块,以便编写正则表达式和RewriteRules
。它们当然不代表完整的正则表达词汇,但它们是一个很好的起点,应该帮助您阅读基本的正则表达式,以及编写自己的正则表达式。
字符 | 含意 | 示例 |
---|---|---|
. |
匹配任何单个字符 | c.t 可匹配cat , cot 和 cut 等。 |
+ |
重复上一个匹配一次或多次 | a+ 匹配a ,aa ,aaa 等。 |
* |
重复前一个匹配零次或多次。 | a* 匹配a+ 匹配的所有相同内容,但也匹配空字符串。 |
? |
使匹配可选。 | colou?r 匹配 color 和 colour |
^ |
称为锚点,匹配字符串的开头。 | ^a 匹配以a 开头的字符串 |
$ |
另一个锚点,它匹配字符串的结尾。 | a$ 匹配以a 结尾的字符串。 |
( ) |
将多个字符组合到一个单元中,并捕获匹配以用于反向引用。 | (ab)+ 匹配ababab - 也就是说,+ 适用于组。 |
[ ] |
字符类 - 匹配其中一个字符。 | c[uoa]t 匹配 cut , cot 或者 cat 。 |
[^ ] |
负字符类 - 匹配未指定的任何字符。 | c[^/]t 匹配 cat 或 c=t ,但是不匹配c/t 。 |
正则表达式反向引用可用性
这里必须记住一件重要的事情:无论何时在Pattern或其中一个CondPattern中使用括号,都会在内部创建后引用,它可以与字符串$N
和%N
一起使用(见下文)。这些可用于创建RewriteRule
的Substitution
参数或RewriteCond
的TestString
参数。
RewriteRule
模式中的捕获(反直觉地)可用于所有前面的RewriteCond
指令,因为RewriteRule
表达式在各个条件之前被计算。
下图显示了后向引用转移到哪些位置以进行扩展,以及说明RewriteRule
,RewriteCond匹配的流程。在接下来的章节中,我们将探索如何使用这些反向引用,所以不要担心。
在此示例中,/test/1234
的请求将转换为/admin.foo?page=test&id=1234&host=admin.example.com
。
RewriteRule基础
RewriteRule由三个以空格分隔的参数组成,它们分别是 -
Pattern
:传入的URL应受规则影响;Substitution
:匹配请求应在何处发送;[flags]
:影响重写请求的选项。
Pattern是一个正则表达式。它最初(对于第一个重写规则或直到发生替换)与传入请求的URL路径(主机名之后但在任何指示查询字符串开头的问号之前)或者在每个目录中匹配上下文,针对相对于定义规则的目录的请求路径。一旦发生替换,后面的规则将与替换值进行匹配。
Substitution
有三种表达格式:
资源的完整文件系统路径
RewriteRule "^/games" "/usr/local/games/web"
这会将请求映射到文件系统上的任意位置,就像
Alias
指令一样。资源的Web路径
RewriteRule "^/foo$" "/bar"
如果
DocumentRoot
设置为/usr/local/apache2/htdocs
,则此指令会将对http://example.com/foo
的请求映射到路径/usr/local/apache2/htdocs/bar
。绝对URL
RewriteRule "^/product/view$" "http://site2.example.com/seeproduct.html" [R]
这告诉客户端为指定的URL发出新请求。
Substitution
还可以包含对Pattern匹配的传入URL路径部分的反向引用。如下:
RewriteRule "^/product/(.*)/view$" "/var/web/productdb/$1"
变量$1
将替换为Pattern中括号内的表达式匹配的任何文本。例如,对http://example.com/product/r14df/view
的请求将映射到路径/var/web/productdb/r14df
。
如果括号中有多个表达式,则它们在变量$1
,$2
,$3
等中按顺序可用。
重写标志
可以通过在规则末尾应用一个或多个标志来修改RewriteRule
的行为。例如,通过应用[NC]
标志,可以使规则的匹配行为不区分大小写:
RewriteRule "^puppy.html" "smalldog.html" [NC]
重写条件
可以使用一个或多个RewriteCond
指令来限制将受以下RewriteRule
约束的请求类型。第一个参数是描述请求特征的变量,第二个参数是必须与变量匹配的正则表达式,第三个可选参数是修改匹配评估方式的标志列表。
例如,要将来自特定IP范围的所有请求发送到其他服务器,可以使用:
RewriteCond "%{REMOTE_ADDR}" "^10\.2\."
RewriteRule "(.*)" "http://intranet.example.com$1"
如果指定了多个RewriteCond
,则它们必须全部匹配要应用的RewriteRule
。例如,要拒绝在查询字符串中包含单词hack
的请求,除非它们还包含包含单词go
的cookie,可以使用:
RewriteCond "%{QUERY_STRING}" "hack"
RewriteCond "%{HTTP_COOKIE}" "!go"
RewriteRule "." "-" [F]
请注意,感叹号指定了否定匹配,因此仅当cookie不包含go
时才应用该规则。
RewriteConds
中包含的正则表达式中的匹配项可以使用变量%1
,%2
等作为RewriteRule
中的替换的一部分。例如,这将根据用于访问的主机名将请求定向到其他目录网站:
RewriteCond "%{HTTP_HOST}" "(.*)"
RewriteRule "^/(.*)" "/sites/%1/$1"