Ответ 1
Флаг 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]