Переписать правило Mod_Rewrite, сводящее меня с ума - PullRequest
2 голосов
/ 24 марта 2012

У меня .htaccess следующим образом, и некоторые правила противоречат друг другу - мне нужно как-то сделать условие, чтобы они не

RewriteEngine On
RewriteRule ^search$ results_template.php [L]
RewriteRule ^load-([a-z0-9-]+)$ index.php?key=$1 [L]
RewriteRule ^([a-z0-9-]+)$ http://domain.com/share/index.php?key=$1 [L]

Файл .htaccess расположен в http://domain.com/directory/.htaccess


Предполагается, что первое правило просто переписывает имя search в results_template.php и прекращает обработку других правил

http://domain.com/directory/search

загружает

http://domain.com/directory/results_template.php


Второе правило должно взять abcdef-1 из

http://domain.com/directory/load-abcdef-1

и отправить его в качестве параметра

http://domain.com/directory/index.php?key=abcdef-1, а затем остановите обработку правил.


Третье правило должно взять abcdef-1 из

http://domain.com/directory/abcdef-1

и отправить егов качестве параметра

http://domain.com/share/index.php?key=abcdef-1 и затем прекратить обработку правил.


Проблема, с которой я сталкиваюсь, заключается в том, как бы я ни старался, чтобы они хорошо играли вместе, когда бы я ни попросил1045 *http://domain.com/directory/search третье правило вызывается, и меня перенаправляют.

Я уверен, что это просто полная усталость или полная глупость, но я был на этом маленькомтеперь слишком много часов, поэтому любая помощь будет действительно полезной.Спасибо

Ответы [ 3 ]

1 голос
/ 25 марта 2012

Вам нужно добавить флаг [NS] в третье правило. Это заставляет это не стрелять на внутренних подзапросах

1 голос
/ 25 марта 2012

Ваша проблема в том, что @Jan объяснил, что при первом выполнении идентификатора перезаписи search становится results_template.php.Чтобы понять это полностью, я добавлю, что тег [L] на перезаписи действительно останавливает перезапись и проталкивает результирующий путь к Apache, но на самом деле внутреннее перенаправление выполняется в apache, а mod-rewrite повторно-применяется после этого внутреннего перенаправления.

Это самое сложное для понимания с помощью переписывания модов.Использование RewriteLog и RewriteLogLevel может значительно помочь вам обнаружить такие проблемы при работе с этими не очень простыми правилами.

Нет, решение, предоставленное Яном, не будет работать, но существует более общее решение.Если вы хотите, чтобы ваши правила применялись только один раз, только по URL-адресу, предоставленному браузерами, и если вы не объединяете несколько уровней перенаправлений, тогда самый простой способ убедиться, что ваши правила - , предотвращает их применение после внутреннегоперенаправление .И это можно сделать, проверив перед каждым правилом, что переменная окружения REDIRECT_STATUS пуста

# prevent this rule from being applied after first pass
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ...

EDIT

Но я только что прочитал @baynezy(+1) ответ и тег [NS] или [nosubreq], кажется, делают то же самое.Вы должны попробовать это тоже.

1 голос
/ 24 марта 2012

Вам понадобятся RewriteConds:

RewriteEngine On
RewriteBase /directory
RewriteRule ^search$ results_template.php [L]
RewriteRule ^load-([a-z0-9-]+)$ index.php?key=$1 [L] 
RewriteCond %{QUERY_STRING} !^results_template.php
RewriteRule ^([a-z0-9-]+)$ http://domain.com/share/index.php?key=$1 [L]

Например, пользователь запрашивает / ищет, затем запрос преобразуется в results_template.php.С этим новым запросом /results_template.php все правила проверяются снова и, конечно, последнее правило подходит, поскольку оно является наиболее общим.

...