多个.htaccess文件中多个mod_rewrite规则的优先级是什么?

eme*_*his 8 apache .htaccess mod-rewrite url-rewriting

我知道[L]以下重写规则意味着它是"最后一个",但我不清楚范围是什么

例如,当有多个.htaccess文件时,有些文件[L]会被应用?

例:

root.com/subdirectory1/subdirectory2

  ^           ^            ^      
  |           |            |
  A           B            C
Run Code Online (Sandbox Code Playgroud)

如果每个目录中都有.htaccess文件...

  1. 他们会以什么顺序申请?
  2. 如果他们互相矛盾哪个优先?
  3. 他们是连续申请吗?第一个结果是否传递到下一个?
  4. 是否会在较早(或相同)的文件中匹配来自后来规则的RESULT?
  5. 如果[L]在早期文件中有其他文件被考虑?

Jon*_*Lin 14

[L]标志确实意味着"最后",但它仅适用于当前范围中的规则.根据您的问题,它仅适用于htaccess文件中的规则.如果子目录中有规则,则父目录中的任何规则都会被抛出窗口.它们根本不应用,除非您使用该RewriteOptions Inherit指令(将从父htaccess文件的任何规则附加到规则的末尾).

举个例子:

root.com/subdirectory1/subdirectory2
  ^           ^            ^      
  |           |            |
  A           B            C
Run Code Online (Sandbox Code Playgroud)

如果A,B和C中有htaccess文件,并且在所有3中都有重写规则,如果有人请求http://root.com(您的"root.com"目录),则只应用A中的规则.如果有人请求http://root.com/subdirectory1,则只应用B中的规则,并忽略A中的任何规则(不带Inherit选项).同样,如果有人去http://root.com/subdirectory1/subdirectory2,那么只有C中的规则才会被应用,如果没有继承选项的话.

[L]标志在任何一个中都没有播放,因为此处的范围仅在htaccess文件的规则内.另请注意,[L]这并不一定意味着"停止重写此处 ",因为重写引擎将循环,直到进入引擎的URI停止更改.这[L]意味着在重写引擎的循环的当前迭代中停止重写.


关于循环内容的更多细节:

在URL处理管道期间,apache尝试将URL映射到文件或资源.许多不同的模块都有一个在处理管道中起作用的部分,比如mod_rewrite或mod_proxy或mod_alias.在任何时候,这个URI都可以改变,被标记为被重定向,被标记为被代理,被标记为抛出错误等等.当URI到达mod_rewrite时,重写引擎从vhost配置中收集一堆规则,适当的htaccess文件; 注意,这里有2个不同的范围.每个规则范围都应用于URI,如果没有规则匹配,则完成mod_rewrite.如果其中一个规则匹配,则存在内部重定向,这意味着URI已更改,然后重定向回处理管道和mod_rewrite.因此,再次应用相同的规则范围,并且如果其中一个规则匹配并应用,则同样的事情再次发生在规则循环中.您可以在vhost/server config中设置一个指令来设置LimitInternalRecursion这些内部重定向的限制.如果重写引擎循环(即重定向回自身)的次数超过此限制(我认为默认值为10),则会出现500 Internal Server错误.

这可能听起来很奇怪但是有很多例子想要这样做.示例:_从URI中删除所有内容并替换为-:

RewriteRule ^(.*)_(.*)$ /$1-$2 [L]
Run Code Online (Sandbox Code Playgroud)

如果URI是/a_b_c_d_foo第一次,URI变为/a_b_c_d-foo,然后它循环并变为`/a_b_c-d-foo,然后再次,/a_b-c-d-foo并在第五次你得到/a-b-c-d-foo.它将再次循环但由于^(.*)_(.*)$模式不匹配,URI将通过重写引擎并且循环停止.

当人们创建不考虑循环的规则时会出现问题,例如:重写/<anything>/foo/<anything>:

RewriteRule ^(.*)$ /foo/$1 [L]
Run Code Online (Sandbox Code Playgroud)

如果URI是/bar第一次重写URI,那么/foo/bar这就是所需的结果.但是URI在内部被重定向回重写引擎并且相同的规则再次匹配,导致:/foo/foo/bar,然后再次:/foo/foo/foo/bar,再次:/foo/foo/foo/foo/bar,直到达到内部递归限制并且您得到500服务器错误.