所以我正在为一个网站开发CSS / JS压缩系统,基本上有以下htaccess
RewriteEngine On
...
RewriteRule ^css/images/(.*)$ images/site/$1?%{QUERY_STRING} [L]
RewriteRule ^css/([0-9a-fA-F]{32})$ assets.php?hash=$1 [L]
RewriteCond %{HTTP_HOST} ^www.site.com [NC]
RewriteRule ^(.*)$ http://site.com/$1 [L,R=301]
RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]
php_flag register_globals off
php_flag magic_quotes_gpc off
php_flag register_long_arrays off
# 404 Handler
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1&%{QUERY_STRING}
现在assets.php没有收到哈希调用,而是index.php - 如果我删除了行RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]
它工作正常但我不知道为什么 - 资产重写RewriteRule ^css/([0-9a-fA-F]{32})$ assets.php?hash=$1 [L]
上的[L]标志是否应该阻止执行任何进一步的重写?我对这里发生的事情感到困惑。
你可能会对此有所了解。非常感谢。
答案 0 :(得分:7)
L
标志表示“不再在规则集中执行任何规则”,这很奇怪并不意味着mod_rewrite
不再执行任何规则。
当您在每个目录上下文中指定mod_rewrite
指令时,例如服务器或虚拟服务器配置的.htaccess
或Directory
部分,重写在Apache处理的后期阶段。为了在这里发挥作用,mod_rewrite
必须在每次重写URL时执行内部重定向。
由于您的重写可能会指向另一个目录,mod_rewrite
会将自己指定为此重定向的处理程序,以便它可以通过它在您发送请求的新位置找到的任何规则。通常,由于您只处理根目录中的单个.htaccess
文件,因此“新”位置中的规则恰好是首先导致重写的规则。
因此,在您的情况下,会发生以下情况:
/css/A01EF
mod_rewrite
启动规则集^css/([0-9a-fA-F]{32})$ -> assets.php?hash=A01EF
L
标志停止重写并强制内部重定向到assets.php?hash=A01EF
mod_rewrite
重新启动规则集^([a-zA-Z0-9_.-]+)$
- > index.php?url=assets.php&hash=A01EF
(顺便说一下,你可以使用QSA
)L
标志停止重写并强制内部重定向到index.php?url=assets.php&hash=A01EF
这个循环很可能会继续,但是mod_rewrite
会识别出你重定向到同一页面并在此之后忽略了你的重写。
这整个过程恰好是两个条件的原因......
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
...在.htaccess
mod_rewrite
规则集中非常常见,因为它们提供了一种简单的方法来确定URL是否已经被重写为预期的实际资源。您可以使用它们,也可以在请求被重写为index.php
时排除assets.php
重写:
RewriteCond %{REQUEST_URI} !^/assets.php
RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]