Apache RewriteRule L 标志无效

Apache rewrite 规则解析时,把 uri 转换成 target 后,还要重新验证所有规则。

如果你写了多条规则,按优先级排列,需要注意了,[L] 这个 flag 可能不是你想象的那么简单。

比如:

RewriteRule ^apple/(.*) apple.php [L]

RewriteRule ^orange/(.*) orange.php [L]

RewriteRule ^(.*)$ index.php [QSA,L]

当你的请求是 www.leakon.com/apple/about/iPhone,你猜 Apache 会执行到哪里?

很不幸地,执行到了 index.php 上,不是你想象的 apple.php 。

为啥?

 

因为虽然能匹配 ^apple/(.*),但在内部 Apache 把 /apple/about/iPhone 转换为 apple.php ,然后要重新从头开始验证每一条规则。

此时 apple.php 已经不匹配  ^apple/(.*) 和 ^orange/(.*),最后走到 ^(.*)$,在内部又转换为 index.php,然后再次从头开始检验。

到最后,发现 index.php 就是 index.php,好,停止解析,运行 index.php。

那咋办?

 

改成这样:

RewriteRule ^apple/(.*) apple.php [L]

RewriteRule ^apple.php – [L]

RewriteRule ^orange/(.*) orange.php [L]

RewriteRule ^orange.php – [L]

RewriteRule ^(.*)$ index.php [QSA,L]

 

啥意思?

 

– [L]

There is a special substitution string named ‘-‘ which means: NO substitution! Sounds silly? No, it is useful to provide rewriting rules which only match some URLs but do no substitution, for example, in conjunction with the C (chain) flag to be able to have more than one pattern to be applied before a substitution occurs.

大致意思是说 “-” 意味着不要做 uri 替换。

 

在我的例子里,就是告诉 Apache 转换到 apple.php,就可以匹配了,不用再做后续任何解析。

 

16:00 – 24:00,我的时间啊。。。

Tags:

Leave a Reply

Your email address will not be published.

*