因为工作须要,查了一下Apache的文档,对当中反向引用和条件的运行做了理解和实验,以下是对Apache 2.2文档的摘录,并在上面做了实验的样例说明,希望能给一些须要深入理解的一些帮助。

其它部分就不做很多其它的说明,看文档就可以。

Apache的mod_rewrite是提供了强大URL操作的杀手级模块,能够实现差点儿全部你梦想的URL操作,其代价是你必须接受其复杂性,由于mod_rewrite对于刚開始学习的人的主要障碍就是不easy理解和运用,即使是Apache专家有时也会发掘出mod_rewrite的新用途。换句话说:你或者是打退堂鼓永不再用,或者是喜欢它并一生受用。眼下存在这样一种倾向:很多刚開始学习的人仅仅是把URL重写规则当着是会变戏法的魔咒,而并未在使用中真正理解这些规则的含义。

本篇文档试图给出充分的背景知识,以便于刚開始学习的人随后的理解,而不是盲目的复制和粘贴。

mod_rewrite使用的是Perl兼容的正則表達式语法。本文不打算具体解说正則表達式语法,你能够到PCRE man page, Perl regular expression man page, Mastering Regular Expressions, by Jeffrey Friedl获得这些内容。

RewriteRule指令的说明部分有一个简单的正則表達式语法简单介绍,能够去參考一下。

另外须要说明的是能够在表达式的最前面加上一个感叹号('!')表示不匹配,只是这样的使用方法并不符合正則表達式语法。

正則表達式的反向引用能力

这是非常重要的一点:一旦在Pattern或者CondPattern中使用了圆括号,就会建立内部的反向引用,能够使用$N和%N来调用(见下述),而且在Substitution和TestString中都有效。图-2说明了反向引用被转换和展开的位置。

图-2: The back-reference flow through a rule.

内部处理

此模块的内部处理极为复杂,可是为了使一般用户避免犯低级错误,也让管理员能充分利用其功能,在此仍然做一下说明。

API阶段

首先,你必须了解Apache是分若干阶段来处理HTTP请求的。Apache API对每一个阶段都提供了一个hook程序。mod_rewrite使用两个hook程序:其一,从URL到文件名称的转换hook(用在读取HTTP请求之后、授权開始之前); 其二,修正hook(用在授权阶段和读取文件夹级配置(.htaccess)之后、内容处理器激活之前)。

所以,Apache收到一个请求而且确定了响应主机(或虚拟主机)之后,重写引擎即開始处理server级配置中的全部mod_rewrite指令(此时处于从URL到文件名称转换的阶段),此阶段完毕后,终于的数据文件夹便确定了。接下来进入修正程序段并触发文件夹级配置中的mod_rewrite指令。这两个阶段并非泾渭分明的,但都实施了把URL重写成新的URL或者文件名称。尽管API最初不是为此目的而设计的,可是如今它已经成为了API的一种用途。记住下面两点,会有助于更好地理解:

尽管mod_rewrite能够将URL重写为新的URL或文件名称,甚至将文件名称重写为新的文件名称,可是之前的API仅仅提供从URL到文件名称的hook。在Apache 2.0中,添加了两个丢失的hook以使得处理过程更加清晰。只是这样做并没有给用户带来麻烦,用户仅仅需记住这样一个事实:借助从URL到文件名称的hook比最初API设计的目标功能更强大。

令人难以置信的是,mod_rewrite还提供了文件夹级的URL操作(.htaccess文件),而这些文件必须在将URL转换成文件名称之后才会被处理(这是必须的,由于.htaccess存在于文件系统中)。换句话说,依据API阶段,这时再处理不论什么URL操作已经太晚了。为了解决这个"鸡和蛋"的问题,mod_rewrite使用了一个小技巧:在进行一个文件夹级的URL/文件名称操作时,先把文件名称重写回对应的URL(通常这个操作是不可行的,可是參考以下的RewriteBase指令就能明确它是怎么实现的了),然后,对这个新的URL建立一个新的内部的子请求,再又一次開始API阶段的运行。

另外,mod_rewrite尽力使这些复杂的操作对用户透明。但仍须记住:server级的URL操作速度快并且效率高,而文件夹级的操作因为这个"鸡和蛋"的问题速度较慢并且效率也低。但从还有一个側面看,这却是mod_rewrite得以为一般用户提供(局部限制的)URL操作的唯一方法。

牢记这两点!

规则集的处理

当mod_rewrite在这两个API阶段中開始运行时,它会读取配置结构中配置好的 (或者是在服务启动时建立的server级的,或者是在遍历文件夹採集到的文件夹级的)规则集,然后,启动URL重写引擎来处理(带有一个或多个条件的)规则集。不管是server级的还是文件夹级的规则集,都是由同一个URL重写引擎处理,仅仅是终于结果处理不同而已。

规则集中规则的顺序是非常重要的,由于重写引擎是按一种特殊的顺序处理的:逐个遍历每一个规则(RewriteRule指令),假设出现一个匹配条件的规则,则可能回头遍历已有的规则条件(RewriteCond指令)。由于历史的原因,条件规则是前置的,所以控制流程略显冗长,细节见图-1。

图-1:重写规则集中的控制流

可见,URL首先与每一个规则的Pattern匹配,假设匹配失败,mod_rewrite将马上终止此规则的处理,继而处理下一个规则。假设匹配成功,mod_rewrite将寻找相应的规则条件,假设一个条件都没有,则简单地用Substitution构造的新值来替换URL,然后继续处理其它规则;可是假设条件存在,则開始一个内部循环按其列出的顺序逐个处理。对规则条件的处理有所不同:URL并不与模式进行匹配,而是首先通过扩展变量、反向引用、查找映射表等步骤建立一个TestString字符串,然后用它来与CondPattern匹配。假设匹配失败,则整个条件集和相应的规则失败;假设匹配成功,则运行下一个规则直到全部条件运行完成。假设全部条件得以匹配,则以Substitution替换URL,而且继续处理。

比如以下的配置

RewriteEngine on

#设置Rewrite日志

RewriteLogLevel 9

RewriteLog "C:/Apache/logs/rewrite.log"

RewriteCond $1   ^(.*)/.(.*) [NC]                  (1)

RewriteCond %{HTTP_HOST}   !^(.*)/.(.*)/.(.*)      (2)

RewriteRule ^/(.*)         /$1?ID=%1               (3)

#RewriteCond ...............                              (4)

#RewriteRule ^/(.*) ............                            (5)

如果在浏览器中输入 http://www.domain.com/index.php,server端将会进行例如以下操作

规则集合的运行:逐个遍历每一个规则(RewriteRule指令),发现第(3)行,则用输入 /index.php作为RewriteRule的Pattern进行匹配,假设匹配不成功,则会继续往下处理其它的RewriteRule。假设成功,则会去寻找本条RewriteRule前面的全部RewriteCond,然后从第找到的第一个RewriteCond開始,建立TestString字符串,然后用它来与CondPattern匹配。假设匹配失败,则整个条件集和相应的规则失败;假设匹配成功,则运行下一个规则直到全部条件运行完成。假设全部条件得以匹配,则以Substitution替换URL,而且继续处理。

上面的样例,假设运行到(5),则仅仅会有(4)这个RewriteCond被处理,(3)前面的(1)(2)不会再次被处理,假设開始运行的时候(3)RewriteRule没有匹配,则(1)(2)就不会有被运行的机会。

反向引用:

从前面的样例和上面的图能够看出,

Substitution能够反向引用当前Pattern中的匹配的分组成分(圆括号!)。

引用方法是: $N  (0 <= N <= 9)

也能够反向应用RewriteCond条件中最后符合的条件中的分组成分(圆括号!)。记住是最后一个匹配成功的。

引用方法是: %N  (1 <= N <= 9)

相同,TestString中能够包括反向引用当前匹配的RewriteRule的Pattern部分的匹配的分组成分(圆括号!)。

引用方法是: $N  (0 <= N <= 9)

从处理图看,仅仅能对该RewriteCond前面的被成功处理过的CondPattern分组成分(圆括号!)进行引用,即条件(2)能够对(1)进行反向引用。

Apache Rewrite 理解的更多相关文章

  1. .htaccess中的apache rewrite规则写法详解

    .htaccess中的apache rewrite写法: 1 RewriteEngine On 2 RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ 3 Rewr ...

  2. Apache Rewrite 规则详解

    在开篇之前: 我想说这篇文章其实是我刚刚接触Rewrite的时候学习的文档,应属转载,但是在这里我不想写明原地址,原因是文章中大多数给出的配置命令经实验都是错误的.需要原文的可以在谷歌上搜索一下&qu ...

  3. Apache rewrite

    Apache rewrite mod_rewrite简介和配置 实URL跳转隐藏真实地址 拟目录 域名跳转 防止盗链 Apache配置支持httpd.conf配置.htaccess配置 启用rewri ...

  4. Apache Rewrite url重定向功能的简单配置

    http://www.jb51.net/article/24435.htm 1.Apache Rewrite的主要功能 就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则表达式规范.平时帮助我 ...

  5. HTTP POST请求的Apache Rewrite规则设置

    最近自测后端模块时有个业务需求需要利用WebServer(我用的是Apache)将HTTP POST请求转发至后端C模块,后端处理后返回2进制加密数据.http post请求的url格式为:     ...

  6. Apache rewrite地址重写

    Apache-rewrite+13个经典案例Apache 重写规则的常见应用(rewrite)一:目的 如何用Apache重写规则来解决一些常见的URL重写方法的问题,通过常见的 实例给用户一些使用重 ...

  7. Apache Rewrite(大小写)

    1.Rewrite规则简介: Rewirte 主要的功能就是实现URL的跳转,它的正则表达式是基于Perl语言.可基于服务器级的(httpd.conf)和目录级的 (.htaccess)两种方式.如果 ...

  8. Apache Rewrite规则详解[转]

    1.Rewrite规则简介:Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Perl语言.可基于服务器级的(httpd.conf)和目录级的(.htaccess)两种方式.如果要想用 ...

  9. centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 访问控制 apache rewrite 配置开机启动apache tcpdump 第二十节课

    centos    LAMP第二部分apache配置  下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转  配置apache的访问日志  配置静态文件缓存  配置防盗链 ...

随机推荐

  1. Android性能优化---布局优化

    我们从事Android开发编写布局的时候大多数是使用XML来布局,这给我们带来了方便性,这样操作可以布局界面的代码和逻辑控制的Java代码分离出来,使程序的结构更加清晰.明了.特别的复杂的布局,但是这 ...

  2. Codeforces Round #309 (Div. 2) C

    题意: 就是给出总共同拥有k种颜色.每种颜色有ki种,排列必须满足第i+1种的最后一种颜色必须在第i种最后一种颜色的后面,其它颜色任意.总共同拥有多少种排列点的方法. 分析: 如果d[i]表示前i种的 ...

  3. elf格式分析

    近期研究了一下elf文件格式,发现好多资料写的都比較繁琐,可能会严重打击学习者的热情,我把自己研究的结果和大家分享,希望我的描写叙述可以简洁一些. 一.基础知识 elf是一种文件格式,用于存储Linu ...

  4. LLVM每日谈21 一些编译器和LLVM/Clang代码

    作者:闪亮宁(snsn1984) 一些自己的收藏LLVM/Clang代码,而他自己写一些一点点LLVM/Clang译器的代码.在这里把这些代码库分享出来,欢迎大家交流探讨. 1.crange http ...

  5. 专注UI——有用技术:模糊搜索

    在如今的项目中.须要做模糊搜索,在曾经技术的基础上非常快得完毕了第一版.大家先看看第一版的效果,我们一会做评论: 0基础: 我们可能部分源代码(附件中会有所有源代码) <span style=& ...

  6. 一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用

    一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用 先上图: 现在的智能控制都是基于微控制器,随着智能的手持终端的普及,基于智能终端的控制就会越来越普遍. WIFI便是其中的一种.W ...

  7. PAT-B 1015. 德才论(同PAT 1062. Talent and Virtue)

    1. 在排序的过程中,注意边界的处理(小于.小于等于) 2. 对于B-level,这题是比較麻烦一些了. 源代码: #include <cstdio> #include <vecto ...

  8. Wix打包系列(七) 添加系统必备组件的安装程序

    原文:Wix打包系列(七) 添加系统必备组件的安装程序 我们知道在vs的打包工程中添加系统必备组件是一件很容易的事情,那么在wix中如何检测系统必备组件并在安装过程中安装这些组件.这里以.Net Fr ...

  9. 阿里云免费试用之体验——阿里云serverECS试用心得

    自上次參加了阿里云的开发人员大会回来 心里就一直惦记着阿里云 由于曾经各种各样什么的server也用了不少 年前開始接触阿里云 一直没有给予很多其它的关注 參加了这次的开发人员大会后 就想更进一步的了 ...

  10. 【cocos2d-x不要在生产白片步骤】第二项:制作Block分类

    由于游戏非常多使用阻断,因此,我们创建了一个单独的类中Block. 于Blcok.h声明了两个初始化函数: static Block* createWithArgs(Color3B color, Si ...