| 说明: | 提供了一个基于规则的实时转向URL请求的引擎 |
|---|---|
| 状态: | Extension |
| 模块名: | rewrite_module |
| 源文件: | mod_rewrite.c |
| 兼容性: | 包含在Apache 1.3及其更新版本中 |
``The great thing about mod_rewrite is it gives you all the configurability and flexibility of Sendmail. The downside to mod_rewrite is that it gives you all the configurability and flexibility of Sendmail.''
-- Brian Behlendorf
Apache Group
`` Despite the tons of examples and docs, mod_rewrite is voodoo. Damned cool voodoo, but still voodoo. ''
-- Brian Moore
bem@news.cmc.net
欢迎来到mod_rewrite, URL操作的瑞士军刀!
此模块提供了一个基于规则的(使用正则表达式分析器的)实时转向URL请求的引擎。 支持每个规则可以拥有不限数量的规则以及附加条件规则的灵活而且强大的URL操作机制。 此URL操作可以取决于各种测试,比如服务器变量、环境变量、HTTP头、时间标记, 甚至各种格式的用于匹配URL组成部分的查找数据库。
此模块可以操作URL的所有部分(包括路径信息部分), 在服务器级的(httpd.conf)和目录级的(.htaccess)配置都有效, 还可以生成最终请求串。此重写操作的结果可以是内部子处理,也可以是外部请求的转向, 甚至还可以是内部代理处理。
但是,所有这些功能和灵活性带来一个问题,那就是复杂性, 因此,不要指望一天之内就能看懂整个模块。
此模块从1997年7月起为Apache Group所专用,由以下这些人创建于1996年4月
http://www.uplinux.com/download/doc/apache/ApacheManual/mod/mod_rewrite.html
| clubadmin 发表于 2006-08-22 03:03 | #1 |
此模块的内部处理极为复杂,但是,为了使一般用户避免犯低级错误, 也让管理员能充分利用其功能,在此仍然做一下说明。 API程序段首先,你必须了解,Apache是通过若干程序段来处理HTTP请求的。 Apache API 对每个程序段提供了一个hook程序。 Mod_rewrite使用两个hook程序: 其一是,URL到文件名的转译hook,用在读取HTTP请求之后,而在授权开始之前; 其二是,修正hook,用在授权程序段和读取目录级配置文件( 所以,Apache收到一个请求并且确定了响应主机(或者是虚拟主机)之后, 重写引擎即开始执行URL到文件名程序段,以处理服务器级的配置中所有的mod_rewrite指令。 在最终数据目录确定以后,进入修正程序段并触发目录级配置中的mod_rewrite指令。 这两个程序段并不是泾渭分明的,但都实施把URL重写成新的URL或者文件名。 虽然API最初不是为此设计的,但它已经成为API的一种用途, 而在Apache 1.x 中这是mod_rewrite唯一的实现方法。 记住以下两点,会有助于更好地理解:
牢记这两点! 规则集的处理当mod_rewrite在这两个程序段中开始执行时,它会读取配置结构中的配置好的 (或者是在服务启动时建立的服务器级的,或者是Apache核心在遍历目录采集到的目录级的)规则集, 随后,启动URL重写引擎来处理(带有一个或多个条件)的规则集。 无论是服务器级的还是目录级的规则集,都是由同一个URL重写引擎处理,只是处理结果不同而已。 规则集中规则的顺序是很重要的,因为重写引擎是按一种特殊的(非常规的)顺序处理的, 其原则是:逐个遍历每个规则(
可见,URL首先与每个规则的Pattern匹配, 如果匹配不成功,mod_rewrite立即终止此规则的处理,继而处理下一个规则。 如果匹配成功,mod_rewrite寻找响应的规则条件,如果一个条件都没有, 则简单地用Substitution构造的新的值来替换URL,然后继续处理其他规则。 如果条件存在,则开始一个内部循环按其列出的顺序逐个处理。 对规则的条件的处理有所不同:URL并不与pattern匹配, 而是,首先通过扩展变量、反向引用、查找映射表等步骤建立一个TestString的字符串, 随后,用它来与CondPattern匹配。如果匹配不成功,则整个条件集和对应的规则失败; 如果匹配成功,则执行下一个规则直到所有条件执行完毕。 如果所有条件得以匹配,则以Substitution替换URL,并且继续处理。 特殊字符的引用在Apache 1.3.20, TestString and Substitution 字符串中的特殊字符可以用前缀的斜杠来实现转义(即,忽略其特殊含义而视之为普通字符)。 比如,Substitution可以用' 正则表达式的反向引用能力这是很重要的一点:一旦在Pattern或者CondPattern使用了圆括号, 就会建立内部的反向引用,可以使用
虽然mod_rewrite内部处理的这个过程是比较杂乱的, 但是了解这些可以帮助你阅读下文中指令的讲述。 | |
| 返回 | |
| clubadmin 发表于 2006-08-22 03:03 | #2 |
此模块会跟踪两个额外的(非标准的)CGI/SSI环境变量, 注意: 这些变量保持的是其最初被请求时的URI/URL, 即, 在任何重写操作之前的。 其重要性在于他们是重写操作重写URL到物理路径名的原始依据。 举例SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html | |
| 返回 | |
| clubadmin 发表于 2006-08-22 03:14 | #3 |
我们还提供另外一个文档URL Rewriting Guide, 列举了许多基于URL的问题的实用方案,其中你可以找到真实有用的规则集和mod_rewrite的更多信息。 | |
| 返回 | |
| clubadmin 发表于 2006-08-22 03:14 | #4 | ||||||||||||||
在对一个新的URL进行替换时,此模块必须把这个URL重新注入到服务器处理中。 为此,它必须知道其对应的URL前缀或者说URL基准。通常,此前缀就是对应的文件路径。 但是,大多数网站URL不是直接对应于其物理文件路径的,因而一般不能做这样的假定! 所以在这种情况下,就必须用 举例,目录级配置文件内容如下: # 上述例子中,对 For Apache Hackers以下列出了内部处理的详细步骤: Request: 虽然这个过程看来很繁复,但是由于目录级重写的到来时机已经太晚了, 它不得不把这个(重写)请求重新注入到Apache核心中,所以Apache内部确实是这样处理的。 但是:它的开销并不象看起来的那样大,因为重新注入完全在Apache服务器内部进行, 而且这样的过程在Apache内部也为其他许多操作所使用。 所以,你可以充分信任其设计和实现是正确的。 | |||||||||||||||
| 返回 | |||||||||||||||
| clubadmin 发表于 2006-08-22 03:15 | #5 | ||||||||||||||||||||||||
TestString是一个纯文本的字符串,但是还可以包含下列可扩展的成分:
特别注意事项:
CondPattern是条件pattern, 即, 一个应用于当前实例TestString的正则表达式, 即, TestString将会被计算然后与CondPattern匹配. 谨记: CondPattern是一个兼容perl的正则表达式, 但是还有若干增补:
另外,还可以为CondPattern追加特殊的标记
作为
举例: 如果要按请求头中的`` RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*
含义: 如果你使用的浏览器是Netscape Navigator(其识别标志是'Mozilla'), 则你将得到内容最大化的主页,包括Frames等等; 如果你使用的是(基于终端的)Lynx,则你得到的是内容最小化的主页,不包含tables等等; 如果你使用的是其他的浏览器,则你得到的是一个标准的主页。 | |||||||||||||||||||||||||
| 返回 | |||||||||||||||||||||||||
| clubadmin 发表于 2006-08-22 03:16 | #6 | ||||||||||||||
使用该指令可以使此模块无效,而无须注释所有的 注意:默认情况下,重写配置是不可继承的, 即,必须在每个需要的虚拟主机中设置一个 | |||||||||||||||
| 返回 | |||||||||||||||
| clubadmin 发表于 2006-08-22 03:17 | #7 | ||||||||||
此指令设置mod_rewrite为了和 | |||||||||||
| 返回 | |||||||||||
| clubadmin 发表于 2006-08-22 03:17 | #8 | ||||||||||
如果要关闭对重写操作的记录,不推荐把Filename设置为 /dev/null, 因为,虽然重写引擎不能输出记录了,但仍会内部地建立这个日志文件, 它会使服务器速度降低,而且对管理员毫无益处! 要关闭日志,可以删除或注解RewriteLog指令, 或者使用RewriteLogLevel 0! 安全参见Apache Security Tips,其中讲述了,为什么如果存放日志的目录对除了启动服务器以外的用户是可写的会带来安全隐患。举例
| |||||||||||
| 返回 | |||||||||||
| clubadmin 发表于 2006-08-22 03:17 | #9 | ||||||||||||
要关闭重写引擎日志,可以简单地设此值为0,关闭所有的重写操作记录。 使用较高的Level值会使Apache服务器速度急剧下降! 重写日志使用大于2的Level值只用于调试! 举例
| |||||||||||||
| 返回 | |||||||||||||
| clubadmin 发表于 2006-08-22 03:18 | #10 | ||||||||||||
MapName是映射表的名称, 指定了一个映射函数,用于重写规则的字符串替换,它可以是下列形式之一:
如果使用了这样的形式,则会在MapName中查找关键词LookupKey。 如果找到了,则被替换成SubstValue; 如果没有找到,则被替换成DefaultValue, 如果没有指定DefaultValue,则被替换成空字符串。 可以使用下列MapType和MapSource的组合:
注意对于纯文本和DBM格式的文件,已经查找过的关键词会被缓存在内核中,直到映射表的mtime改变了或者服务器重启了。这样,你可以把每个请求都会用到的映射函数放在规则中,这是没有问题的,因为外部查找只进行一次! | |||||||||||||
| 返回 | |||||||||||||