• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • mod_rewrite技术详细信息

    本文档讨论了mod_rewrite和URL匹配的一些技术细节。

    API阶段

    Apache HTTP Server分几个阶段处理请求。在这些阶段的每个阶段,可以调用一个或多个模块来处理请求生命周期的这一部分。阶段包括URL到文件名的转换,身份验证,授权,内容和日志记录。(这不是详尽的清单。)

    mod_rewrite在其中两个阶段(或通常称为“钩子”)中起作用,以影响URL的重写方式。

    首先,它使用URL到文件名转换挂钩,该挂钩在读取HTTP请求之后但开始任何授权之前发生。其次,它使用Fixup挂钩,该挂钩在授权阶段之后,.htaccess在读取每个目录的配置文件(文件)之后,但在调用内容处理程序之前。

    因此,在请求进入并确定了相应的服务器或虚拟主机之后,重写引擎将开始处理mod_rewrite每个服务器配置中出现的所有指令。(即,在主服务器配置文件和<Virtualhost>部分中。)这在URL到文件名阶段发生。

    几步后,一旦找到最终的数据目录,就应用每个目录的配置指令(.htaccess文件和<Directory>块)。这发生在修复阶段。

    在每种情况下,mod_rewrite都会将_rewrite REQUEST_URI到新的URL或文件名。

    在每个目录的上下文中(即,在.htaccess文件和Directory块中),在将URL转换为文件名之后,将应用这些规则。因此,mod_rewrite最初将RewriteRule指令与之进行比较的URL路径是已翻译文件名的完整文件系统路径,并且当前目录路径(包括尾部斜杠)已从前面删除。

    举例说明:如果规则位于/var/www/foo/.htaccess中,并且正在处理对/ foo / bar / baz的请求,则匹配^ bar / baz $之类的表达式。

    如果在每个目录上下文中进行替换,则会使用新的URL发出新的内部子请求,从而重新开始请求阶段的处理。如果替换是相对路径,则RewriteBase伪指令确定替换之前的URL路径前缀。在每个目录的上下文中,必须小心创建规则,这些规则最终(在将来的每个目录重写过程中)将不执行替换操作以避免循环。(有关此问题的进一步讨论,请参见RewriteLooping。)

    由于在每个目录上下文中对URL进行了进一步的处理,因此您需要注意在该上下文中以不同的方式编写重写规则。特别是,请记住,将删除重写规则将看到的URL的开头目录路径。请考虑以下示例以进一步说明。


    Location of ruleRule
    VirtualHost sectionRewriteRule "^/images/(.+)\.jpg""/images/$1.gif"
    .htaccess file in document rootRewriteRule "^images/(.+)\.jpg""images/$1.gif"
    .htaccess file in images directoryRewriteRule "^(.+)\.jpg""$1.gif"
    为了进一步了解mod_rewrite如何在不同上下文中操纵URL,您应该查阅重写期间创建的日志条目。

    规则集处理

    现在,当在这两个API阶段中触发mod_rewrite时,它将从其配置结构中读取已配置的规则集(该规则集本身是在针对每个服务器上下文启动时创建的,或者是针对每个目录上下文在Apache内核的目录遍历期间创建的)。然后,使用包含的规则集(一个或多个规则及其条件)启动URL重写引擎。对于两个配置上下文,URL重写引擎本身的操作是完全相同的。仅最终结果处理有所不同。

    规则集中规则的顺序很重要,因为重写引擎以特殊(但不是很明显)的顺序对其进行处理。规则是这样的:重写引擎按规则(RewriteRule指令)遍历规则集规则,并且当特定规则与之匹配时,可选地通过现有的相应条件(RewriteCond指令)遍历。由于历史原因,首先要给出条件,因此控制流程有些冗长。有关更多详细信息,请参见图1。

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

    首先,URL与每个规则的模式匹配。如果失败,则mod_rewrite立即停止处理此规则,并继续执行下一个规则。如果模式匹配,则mod_rewrite查找相应的规则条件(RewriteCond伪指令,出现在配置中的RewriteRule上方)。如果不存在,则将URL替换为新值,该新值由字符串Substitution构造,并继续其规则循环。但是,如果条件存在,它将启动一个内部循环以按列出的顺序对其进行处理。对于条件,逻辑是不同的:我们没有将模式与当前URL匹配。相反,我们首先通过扩展变量,反向引用,映射查找等来创建字符串TestString,然后尝试将CondPattern与之匹配。如果模式不匹配,则完整的条件集和相应的规则将失败。如果模式匹配,则处理下一个条件,直到没有其他条件可用为止。如果所有条件都匹配,则继续处理,将URL 替换为Substitution