don*_*atJ 1 apache .htaccess mod-rewrite
所以我正在为一个站点开发一个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}
Run Code Online (Sandbox Code Playgroud)
现在assets.php没有接收哈希调用,而是index.php - 如果我删除该行 RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]
它工作正常,但我不知道为什么 - 不应该重写资产重写的[L]标志RewriteRule ^css/([0-9a-fA-F]{32})$ assets.php?hash=$1 [L]阻止执行任何进一步的重写?我对这里发生的事情感到困惑.
任何你可以放在这上面的光都会非常感激.
该L标志说这奇怪的是,并不意味着没有更多的规则会被执行"不规则集,执行任何更多的规则" mod_rewrite.
当您指定mod_rewrite一个目录级的指令,例如用.htaccess或Directory一个服务器或虚拟服务器配置的部分,重写来在Apache处理后期.要在这里发挥其魔力,mod_rewrite每次重写URL时都必须执行内部重定向.
由于您的重写可能会指向另一个目录,因此mod_rewrite将其自身指定为此重定向的处理程序,以便它可以通过它在您发送请求的新位置可能找到的任何规则.通常,由于您只处理.htaccess根目录中的单个文件,因此"新"位置中的规则恰好是首先导致重写的规则.
因此,在您的情况下,会发生以下情况:
/css/A01EFmod_rewrite 启动规则集^css/([0-9a-fA-F]{32})$ -> assets.php?hash=A01EFL flag停止重写并强制内部重定向到 assets.php?hash=A01EFmod_rewrite 再次启动规则集^([a-zA-Z0-9_.-]+)$- > index.php?url=assets.php&hash=A01EF(你可以QSA在这里使用,顺便说一下)L flag停止重写并强制内部重定向到 index.php?url=assets.php&hash=A01EF这个循环很可能会继续,但会mod_rewrite识别出你重定向到同一页面并在此之后忽略了你的重写.
整个过程恰好是两个条件的原因......
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Run Code Online (Sandbox Code Playgroud)
...在.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]
Run Code Online (Sandbox Code Playgroud)