RewriteRule Last [L]标志不起作用?

时间:2011-07-23 03:14:20

标签: apache http mod-rewrite url-rewriting

php_flag display_errors 1
php_value auto_prepend_file init.php
RewriteEngine on 
RewriteRule ^$  /id/authenticate [R]
RewriteRule ^login_openid$  /id/login_openid.php [QSA,L]
RewriteRule ^authenticate$  /id/authenticate.php [QSA,L]
RewriteRule ^facebook$  /id/facebook.php [QSA,L]
RewriteRule ^createfromopenid$  /id/createfromopenid.php [QSA,L]

RewriteRule .* - [L,R=403]

这是我的.htaccess文件。在serverconfig中,我只有AllowOVerride all

如果我请求网址http://mydomain.com/id/authenticate,我会收到403错误。如果我删除最后一条规则,它就可以了。 [L]单位不应该阻止任何进一步的规则发生吗?

编辑:

我的htaccess文件位于子文件夹“id”中,因此规则有效。

2 个答案:

答案 0 :(得分:72)

[L]规则运作良好 - 您只是不知道实际的工作方式。

当Apache看到[L]标志和规则匹配(重写发生)时,Apache将转到下一次迭代,并将从顶部再次开始匹配所有规则。 [L]标记表示“请勿在此次迭代中处理以下的任何规则”。

是的, Apache documentation 并非100%明确(这意味着可以改进),但提供了足够的信息以便最终弄明白。


Apache将在几种情况下停止重写周期:

  1. 根本没有匹配的规则(没有重写);

  2. “立即退出”规则匹配(例如RewriteRule .* - [L]);

  3. 发生重写,但输入的URL和最终的URL是相同的(当“严重”编写的规则将相同的URL重写为同一URL时,在第2到第3次迭代时发生。

    例如RewriteRule (.*) /index.php?page=$1 [L]

    • /hello => /index.php?page=hello
    • 在下一次迭代时,它将重写/index.php => /index.php?page=index.php
    • 并且在第3次迭代时它将是/index.php => /index.php?page=index.php ..现在没有意义;)
  4. 达到重写迭代限制(默认值= 10) - 如果您输入了无限重写周期(该值由LimitInternalRecursion Directive控制)。


  5. 根据上述所有信息,我可以说您当前的规则确实按预期工作。这意味着你必须改变逻辑并摆脱最后一条规则(也许在父.htaccess中处理这个时刻......或者以不同方式处理它 - 所有这些都取决于你的应用程序是如何构建的,我不想做出疯狂的猜测)。

答案 1 :(得分:9)

将其放在cath all规则前面。

RewriteCond %{ENV:REDIRECT_STATUS} !=200

问题在于,一旦处理了[L]标志,确实忽略了所有下一个RewriteRules,但是,文件从begin开始处理AGAIN,现在使用新url。

如果文件已经重定向,这个神奇的条件将不会处理catch all

PS: 如果它不起作用,您可能需要稍微调整一下条件:200!=200^.^$
实际上,变量设置为200以进行重定向,但其他页面(错误和填充)也将其设置为某个值。现在,这意味着您要么检查它是is emptyis not emptyis 200还是is not 200,具体取决于您的需求。