考虑这个简单的规则来向访问者隐藏丑陋的 URL:
RewriteRule ^/CleanPage.html$ /index.php?ugly_parameter=yuck&somevar=12 [L]
此规则似乎在日志中生成了两组“规则运行”。首先,它运行所有规则,直到发现 CleanPage.html 匹配。
此时,它应该已经完成了,但是它却做了一些愚蠢的事情:它采用复杂的 url“index.php?ugly_parameter=yuck&somevar=12”并从头开始尝试将其与另一条规则匹配!
我该如何告诉它“index.php?ugly_parameter=yuck&somevar=12”是我的“最终答案”,而不是浪费时间尝试查看它是否与其他任何内容匹配?我认为这就是“[L]”标志的用途?
答案1
[L] 参数仅表示这是当前重写 URL 上要考虑的最后一条规则,但它不包括内部重定向。
我假设你已经对 RewriteRule 的原始格式做了一些修改,并且你试图在 .htaccess 文件中使用该规则——在这种情况下,你观察到的行为是符合预期的(但在这种情况下,规则将会改为这样RewriteRule ^CleanPage.html$ /index.php?ugly_parameter=yuck&somevar=12 [L]
,即没有前导斜杠),如http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule在 L 旗下。
当您在 .htaccess 文件(或 <Directory> 上下文)中使用 RewriteRule 时,Apache httpd 必须将生成的重写 URL 重新注入 Apache 内核,因为在处理过程中,简单地更改文件名为时已晚——URL 到文件名的解析已经完成,否则 httpd 就不知道在哪里查找您正在使用的 .htaccess 文件。重新注入 URL 基本上会重新启动整个请求过程——包括任何和所有 RewriteRule。
如果要避免这种情况,您必须在 Apache httpd 配置文件中的 <VirtualHost> 上下文中指定规则。在这种情况下,规则可以在更改后续处理之前应用很多次,并且规则只会应用一次。
如果我做出的任何假设是错误的,请发布带有 LogLevel 3 的 RewriteLog 的输出以供进一步分析。