Перепишите проблему - L (ast) не соблюдается? - PullRequest
1 голос
/ 14 августа 2010

Итак, я работаю над системой сжатия 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 не получает хеш-вызов, а скорее индексирует.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], чтобы предотвратить дальнейшее переписывание?Я смущен тем, что здесь происходит.

Любой свет, который вы могли бы пролить на это, был бы очень признателен.

1 Ответ

7 голосов
/ 14 августа 2010

Флаг L говорит: «не выполнять больше правил в наборе правил», что, как ни странно, не означает, что к 100 * * больше не будут выполняться правила.

Когда вы указываете директивы 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...