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

The*_*can 27 apache mod-rewrite http 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]
Run Code Online (Sandbox Code Playgroud)

这是我的.htaccess文件.在我刚刚拥有的serverconfig中AllowOVerride all.

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

编辑:

我的htaccess文件位于子文件夹"id"中,因此规则有效.

Laz*_*One 75

[L]规则工作正常-你只是不知道它是如何实际工作的.

当Apache看到[L]标志和规则匹配(重写发生)时,Apache将进入下一次迭代,并将从顶部再次开始匹配所有规则.该[L]标志表示" 在此迭代中不处理以下任何规则".

是的,Apache文档并非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指令控制).


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

  • @LazyOne,嗯,如上面提到的hakre的END标志呢? (4认同)
  • @Joe作为目标URL的`-`表示不重写,这与#3(迭代开始时的URL =迭代结束时的URL)几乎相同.由于URL没有改变****,Apache将退出循环. (3认同)
  • 根据您的应用程序/重写逻辑,您可以使用此规则:`#不对现有文件执行任何操作``RewriteCond%{REQUEST_FILENAME} -f [OR]``RewriteCond%{REQUEST_FILENAME} -d``RewriteRule.+ - [L]` - 它工作正常. (3认同)
  • @Pacerier是的,它应该完成这项工作(从描述中确切地说是需要的),但它仅在2.3.x版本中可用 - 我个人尚未处理它(所有服务器仍然是v2.2甚至更低版本)并且并不知道它有多广泛.如果您控制整个服务器(可以安装该版本..或者它已经安装),那么你一定要尝试它. (3认同)
  • @Joe让我们根据您的规则提供一个示例:请求URL是`/ id/login_openid`.**初始迭代:**URL被剥离到目录级别并且=`login_openid`.这将匹配规则#2(第5行).发生重写,新URL为`/ id/login_openid.php`,重写进入下一次迭代.**迭代#2**:URL被剥离并且=`login_openid.php`.这将没有规则,除了最后一个规则,它告诉Apache中止请求(发送403响应) - 这就是你当前规则的工作方式. (2认同)
  • @LazyOne,我们如何做"退出现在"?基本上我只想要apache重写*一次*并退出.. (2认同)

Qwe*_*rty 9

把它摆在你的cath all规则面前.

RewriteCond %{ENV:REDIRECT_STATUS} !=200
Run Code Online (Sandbox Code Playgroud)

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

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

PS:如果它不工作,你可能需要调整条件的位:200,!=200,^.,^$.
显然,变量设置200为重定向,但其他页面(错误和填充)将其设置为某个值.现在,这意味着你要么如果它检查is empty,is not empty,is 200或者is not 200,这取决于你所需要的.