Флаг RewriteRule Last [L] не работает? - PullRequest
27 голосов
/ 23 июля 2011
php_flag display_errors 1
php_value auto_prepend_file init.php
RewriteEngine on 
RewriteRule ^$  /id/authenticate [R]
RewriteRule ^login_openid$  /id/login_openid.php [QSA,L]
RewriteRule ^authenticate$  /id/authenticate.php [QSA,L]
RewriteRule ^facebook$  /id/facebook.php [QSA,L]
RewriteRule ^createfromopenid$  /id/createfromopenid.php [QSA,L]

RewriteRule .* - [L,R=403]

Это мой файл .htaccess.В serverconfig у меня просто есть AllowOVerride all.

Если я запрашиваю URL http://mydomain.com/id/authenticate, я получаю 403 ошибку.Если я уберу последнее правило, оно будет работать.Разве квартира [L] не должна допустить дальнейших правил?

Редактировать:

Мой файл htaccess находится в подпапке "id", поэтому правила работают.

Ответы [ 2 ]

74 голосов
/ 23 июля 2011

Правило [L] прекрасно работает - вы просто не знаете, как оно на самом деле работает.

Когда Apache видит флаг [L] и соответствия правил (происходит перезапись), Apache перейдет к следующей итерации и снова начнет сопоставлять все правила сверху. Флаг [L] означает «не обрабатывать никакие правила ниже в этой итерации ».

Да, документация Apache не является на 100% ясной (это означает, что ее можно улучшить), но предоставляет достаточно информации, чтобы со временем это выяснить.


Apache остановит цикл перезаписи в нескольких ситуациях:

  1. Совпадений правил нет вообще (переписывание не произошло);

  2. Правило "выйти сейчас" соответствует (например, RewriteRule .* - [L]);

  3. Произошла перезапись, но входные и конечные URL-адреса совпадают (происходит на 2-й и 3-й итерации, когда «плохо» написанное правило перезаписывает один и тот же URL-адрес на тот же URL-адрес.

    Например RewriteRule (.*) /index.php?page=$1 [L]:

    • /hello => /index.php?page=hello
    • на следующей итерации будет перезаписано /index.php => /index.php?page=index.php
    • и на 3-й итерации это будет /index.php => /index.php?page=index.php .. что сейчас не имеет смысла);
  4. Достигнут предел итерации перезаписи (по умолчанию = 10) - это если вы ввели бесконечный цикл перезаписи (значение контролируется LimitInternalRecursion Directive ).


Со всей вышеупомянутой информацией я могу сказать, что ваши текущие правила работают как положено . Это означает, что вам нужно изменить логику и избавиться от последнего правила (возможно, обработать этот момент в родительском .htaccess .. или обработать его по-другому - все зависит от того, как построено ваше приложение, я не хочу делать дикие догадки ).

9 голосов
/ 25 мая 2014

Поместите это перед вашим cath all правилом.

RewriteCond %{ENV:REDIRECT_STATUS} !=200

Проблема в том, что после обработки флага [L] все последующие RewriteRules действительно игнорируются, однако файл обрабатывается СНОВА с самого начала, теперь с новым URL.

Это магическое условие не будет обрабатывать catch all, если файл уже был перенаправлен.

PS: Если это не сработает, вам может понадобиться немного изменить условие: 200, !=200, ^., ^$.
По-видимому, переменная устанавливается на 200 для перенаправления, но и другие страницы (ошибки и прочее) устанавливают для нее какое-то значение. Теперь это означает, что вы либо проверяете, is empty, is not empty, is 200 или is not 200, в зависимости от того, что вам нужно.

...