Apache mod_rewrite RewriteRule зацикливается, несмотря на флаг L

Apache mod_rewrite RewriteRule зацикливается, несмотря на флаг L

Apache/2.4.54.
Я пытаюсь добиться того, чтобы похожие URL (например, "/anystuff.htm") были перенаправлены извне на "/something", который внутри является "something.html". Но следующие правила вызывают цикл вместо остановки, т.е. "something" сопоставляется

RewriteEngine On
RewriteBase /
RewriteRule ^something$ something.html [L]
RewriteRule ^(some|thing|any|stuff).*/?$ /something [L, R=301,NC]

Но, похоже, директива «L» не оказывает никакого эффекта, поскольку перенаправление на «/something» снова сопоставляется со вторым правилом, что приводит к возникновению цикла.

Тестирование сhttps://htaccess.madewithlove.com/предполагает, что это должно работать как и ожидалось. Я не думаю, что я могу включить ведение журнала :-(

решение1

Флаг Lостанавливает только текущий проход через механизм перезаписи, но не останавливаетвсеобработка. Последующие директивы не обрабатываются немедленно, но (в контексте каталога) процесс перезаписи затем начинается заново... Во время «второго прохода» первое правило больше не соответствует (так как теперь входные данные something.html), но второе правило соответствует, поэтому инициирует перенаправление.

(Механизм перезаписи фактически «зацикливается» до тех пор, пока URL не пройдет без изменений. Директивы легче понять, если использовать их всервер(контекст не каталога), где Lфлаг фактически останавливает всю обработку, поскольку механизм перезаписи выполняет только один проход.)

Однако в Apache 2.4 вы можете использовать этот ENDфлаг вместо этого, чтобы остановить всю обработку механизмом перезаписи (вкаталогконтекст). Например:

RewriteEngine On

RewriteRule ^something$ something.html [END]
RewriteRule ^(some|thing|any|stuff) /something [R=301,NC,L]

(Обратите внимание, что у вас был ошибочныйкосмосв аргументе флагов во втором правиле. Это привело бы к ошибке синтаксического анализа, поэтому я предполагаю, что это была опечатка в вашем вопросе?)

Регулярное выражение во втором правиле (т.е. .*/?$) является излишним.

Использование Lс перенаправлением ( Rфлаг) то же самое, что и END. Вся обработка останавливается.

В вашем примере эта RewriteBaseдиректива излишняя.

NB: Сначала вам следует протестировать перенаправление 302 (временное) и только после того, как вы убедитесь, что оно работает как задумано, менять его на 301 (постоянное). 301-е постоянно кэшируются браузером, поэтому тестирование может быть проблематичным. Следовательно, перед тестированием вам нужно будет очистить кэш браузера (и любого промежуточного звена).

Тестирование https://htaccess.madewithlove.com/показало, что все должно работать так, как и ожидалось.

В отличие от реального сервера, тестер MWL фактически выполняет только «один проход» по правилам, поэтому не может обнаружить циклы перезаписи/перенаправления.


В стороне:Обычно вы должны организовать внешние директивы перенаправления перед внутренними переписываниями. Однако второе правило в вашемпримербудет перенаправлено /somethingна себя, поэтому ваши две директивы в настоящее время зависят от порядка, в котором вы их указали.

Связанный контент