Apache Mod_重写意外行为L标志
我的web应用程序结构是:Apache Mod_重写意外行为L标志,apache,mod-rewrite,Apache,Mod Rewrite,我的web应用程序结构是: /var/www/myapp/ - www/ - index.php - css.php - .htaccess 虚拟主机配置为: <VirtualHost *:80> ServerName www.example.org DocumentRoot /var/www/myapp/www DirectoryIndex index.php index.ht
/var/www/myapp/
- www/
- index.php
- css.php
- .htaccess
虚拟主机配置为:
<VirtualHost *:80>
ServerName www.example.org
DocumentRoot /var/www/myapp/www
DirectoryIndex index.php index.html
<Directory /var/www/myapp/www>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
似乎发生了第一次重定向,但mod_重写并没有停止导致内部重定向。然后,更改后的url再次传递给mod_rewrite,并发生第二次重定向,但现在与第二条规则匹配
我无法理解,因为我放置了[L]标志只是为了确保mod_重写停止
再次感谢您您错过了有关以下方面的一个重要事实: 因此,如果您在这些[
.htaccess
,
]上下文中使用指令,您必须采取明确的步骤来避免规则循环,而不是仅仅依靠[L]标志来终止一系列规则的执行
发件人:;我敢说
这意味着,仅通过使用L
不会产生您想要的效果来阻止内部重定向。内部重定向发生在此处,因为它必须发生,您已使用.htaccess
配置指定了它。L
标志不是防止内部重定向的正确标志
让我们仔细看看您的问题以及实际发生的情况:
我无法理解,因为我放置了[L]标志只是为了确保mod_重写停止
只是您对L
标志的理解有误。它只会在当前重写时停止,这意味着它下面的RewriteRule
指令不会在当前一轮(内部循环)中处理
如果URI更改,则L
将重新注入下一轮(外部循环),如下所示:
为了突出显示L
标志的作用位置以及内部重定向的发生位置,这是一个带有特定(第一个)URI重写注释的相同图形:
它显示L
标志仅退出内部循环,但如果URI已被重写(更改)(如您的情况),则外部循环会注意将更改的URI再次传递给所有重写规则
相反,您可能希望制定一个条件,如手册该部分的以下示例所示:
RewriteBase /
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule ^(.*) /index.php?req=$1 [L,PT]
(,或多或少不是解决方案的一部分,只需注意,因为我引用了示例)
您实际想要使用的是END
标志:
RewriteRule css css.php [END,NC]
但是,如果您有所需的apache版本(在2.3.9及更高版本中提供),请与系统管理员联系。如果没有,您需要使用。hakre的回答很好地说明了正在发生的事情。除了使用END
标志外,您还有几个选项:
- 使用
%{ENV:REDIRECT_STATUS}
防止任何进一步的重写。这将在内部重定向后更改。有关实际发生的情况的更多信息,请参阅:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule css css.php [L,NC]
- 使用
%{THE_REQUEST}
匹配向服务器发出的请求。由于这在内部重定向时不会改变,因此可用于防止进一步重定向
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /css\ HTTP
RewriteRule ^ css.php [L,NC]
- 在查询字符串中使用伪变量。这将允许通过在链接中定义此变量来防止重定向,但我们将在此处使用它来防止多次传递:
RewriteCond %{QUERY_STRING} !noredir=1
RewriteRule css css.php?noredir=1 [L,QSA,NC]
请注意,对于这些示例中的每一个,您都需要为每个规则使用此结构。这很有趣。设置看起来不错,我在我的系统上试过了,效果很好。也许你想打开重写日志,看看到底重写了什么:我已经编辑了消息,你会找到一个日志。只需关注内部重定向:-)请参阅@谢谢您的反馈。这是一个有点难以用语言来描述,所以我认为与图形这应该是更好的。很好的回答,我爱的图表!有史以来最好的mod_重写说明!我完全同意,这是一个极好的解释。另一个变体——但不适用于该变量——是将重写后的URL重写为自身,以便触发now change exit L解析(例如Apache 2.2)。
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /css\ HTTP
RewriteRule ^ css.php [L,NC]
RewriteCond %{QUERY_STRING} !noredir=1
RewriteRule css css.php?noredir=1 [L,QSA,NC]