我理解重写规则之后的[L]
意味着它是“最后一个”,但我不清楚范围是什么
例如,当有多个.htaccess文件时,有些文件会[L]
,哪些会适用?
示例:
root.com/subdirectory1/subdirectory2
^ ^ ^
| | |
A B C
如果每个目录中都有.htaccess文件......
[L]
,是否会考虑其他文件?答案 0 :(得分:14)
[L]
标志确实意味着“最后”,但它仅适用于当前范围中的规则。根据您的问题,它仅适用于htaccess文件中的规则。如果子目录中有规则,则父目录中的任何规则都会被抛出窗口。它们根本不应用,除非您使用RewriteOptions Inherit
指令(将在父htaccess文件的任何规则附加到规则的末尾)。
鉴于你的例子:
root.com/subdirectory1/subdirectory2
^ ^ ^
| | |
A B C
如果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]
并不一定意味着“停止重写 HERE ”,因为重写引擎将循环,直到进入引擎的URI停止更改。 [L]
只是意味着在重写引擎循环的当前迭代中停止重写。
在URL处理管道中,apache尝试将URL映射到文件或资源。许多不同的模块都有一个在处理管道中起作用的部分,比如mod_rewrite或mod_proxy或mod_alias。在任何时候,这个URI都可以改变,被标记为被重定向,被标记为被代理,被标记为抛出错误等等。当URI到达mod_rewrite时,重写引擎从vhost配置中收集一堆规则,适当的htaccess文件;注意,这里有2个不同的范围。每个规则范围都应用于URI,如果没有规则匹配,则完成mod_rewrite。如果其中一个规则匹配,则存在内部重定向,这意味着URI已更改,然后重定向回处理管道和mod_rewrite。因此,再次应用相同的规则范围,并且如果其中一个规则匹配并应用,则同样的事情再次发生在规则循环中。您可以在名为LimitInternalRecursion
的vhost / server配置中设置指令,该配置设置这些内部重定向的限制。如果重写引擎循环(即重定向回自身)的次数超过此限制(我认为默认值为10),则会出现500内部服务器错误。
这可能听起来很奇怪但是有很多例子想要这样做。示例:从URI中删除所有_
并替换为-
:
RewriteRule ^(.*)_(.*)$ /$1-$2 [L]
如果URI是/a_b_c_d_foo
,则第一次将URI更改为/a_b_c_d-foo
,然后将其循环并更改为`/a_b_c-d-foo
,然后再次更改为/a_b-c-d-foo
并通过第5次你得到/a-b-c-d-foo
。它会再次循环但由于^(.*)_(.*)$
模式不匹配,URI会通过重写引擎并且循环停止。
当人们创建不考虑循环的规则时会出现问题,例如:将/<anything>
重写为/foo/<anything>
:
RewriteRule ^(.*)$ /foo/$1 [L]
如果URI为/bar
,那么第一次将URI重写为/foo/bar
时,这就是所需的结果。但URI会在内部重定向回重写引擎,同样的规则再次匹配,导致:/foo/foo/bar
,然后再次:/foo/foo/foo/bar
,再次:/foo/foo/foo/foo/bar
,直到内部递归达到限制,你得到500服务器错误。