2010-11-08 5 views
2

У меня есть подкатегория secure/ с несколькими файлами, на которых я хочу выполнить некоторые простые RewriteRules, просто по умолчанию использую расширение PHP. Мне было трудно заставить их работать, и после некоторых проб и ошибок наткнулся на следующее..htaccess RewriteRule - DOCUMENT_ROOT и RewriteBase

RewriteEngine On 
RewriteBase /secure 

# Force PHP extension if not a directory 
RewriteCond %{DOCUMENT_ROOT}/secure/%{REQUEST_URI} -d 
RewriteRule ^(.*)$ - [L] 

RewriteCond %{DOCUMENT_ROOT}/secure/$1.php -f 
RewriteRule ^((.*/)*[^./]+)/*$ $1.php [L] 

Мое отсутствие понимания вокруг %{DOCUMENT_ROOT} и добавления /secure/. Я полагал, что либо %{DOCUMENT_ROOT}, либо с помощью RewriteBase справится с этим. Однако, каждая из этих частей, кажется, требуется. Я хотел бы знать, почему и что каждый достиг в моем случае.

ответ

10

RewriteBase directive используется mod_rewrite исключительно во время шагов перенаправления и игнорируется во время всей другой обработки. Вопреки тому, что указано в документации, это часто не обязательно, поскольку (как в вашем случае) довольно часто для URL-адреса сопоставляется подкаталоги в файловой системе за пределами DOCUMENT_ROOT.

Итак, что делает директива? Когда ваши правила оцениваются в контексте для каждого каталога, так как они используются при использовании файла .htaccess, URL-адрес передается mod_rewrite очень поздно в цепочке обработки запросов Apache. Это означает, что URL-адрес, возможно, уже частично переведен в путь к файловой системе, поэтому путь в /каталог/подкаталог/файл может быть фактически доступен через веб-сервер через /location/подкаталог/файл.

Это не похоже на проблему, но тот факт, что утеряна статья /location/, создает проблему для mod_rewrite. Чтобы понять, почему, вы должны знать, как mod_rewrite делает возможным переписывание контекста для каждого каталога.

Когда вы выполняете переписывание в файле .htaccess, mod_rewrite повторно вводит измененный запрос в Apache в качестве внутреннего перенаправления, как если бы это был URL-адрес. Это проблематично, поскольку путь запроса может не соответствовать соответствующему URL-адресу. Например, если запрос оказался в /директории/поддиректории/файла (который мы предполагаем, что находится за пределами DOCUMENT_ROOT), мы могли бы это правило в /directory/.htaccess:

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule .* index.php 

Это рассмотрит /подкаталог/файл, решите, что он не был фактическим файлом, и перепишите его на index.php. На этом этапе новый URL-адрес должен быть возвращен Apache для внутреннего перенаправления для завершения перезаписи. Поскольку он не имеет никакой ссылки, он заканчивает отправку всего пути —, то есть он отправляет /directory/index.php. Это не то, что вы хотите, поскольку URL-адрес для доступа к этому местоположению будет фактически /location/index.php. Вот где RewriteBase приходит. Указав

RewriteBase /location/ 

в файле .htaccess, префикс каталога /каталог/ будет выгружена на /место/ как часть этой обработки после перезаписи, в результате чего внутреннее перенаправление на ожидаемый URL-адрес /location/index.php.

Это также имеет последствия с внешними переадресациями.Если вы пытаетесь перенаправить извне с помощью флага [R] только с путём, и путь не имеет ведущей косой черты, весь каталог будет отправлен обратно клиенту описанным выше способом, если он не будет заменен значением, указанным в RewriteBase.

Ни один из этих пунктов не относится к вашей ситуации, поэтому вы должны быть в порядке, не указав RewriteBase.

Переменная %{DOCUMENT_ROOT} - это просто значение переменной DOCUMENT_ROOT Apache, которая задается в конфигурации вашего сервера/виртуального хоста. Он всегда соответствует каталогу, который разрешает запрос /. Для проверок -f и -d требуется полный путь к файловой системе, поэтому %{DOCUMENT_ROOT} должен быть добавлен к относительному пути при их использовании.

Для разрешения пути текущего запроса mod_rewrite позаботится об этом для вас с переменной %{REQUEST_FILENAME}. Например, если предположить, что файл .htaccess живет в вашем/безопасном подкаталоге , вы могли бы изменить ваше правило устанавливается следующим образом:

RewriteEngine On 

# Force PHP extension if not a directory 
RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule^- [L] 

RewriteCond %{REQUEST_FILENAME}.php -f 
RewriteRule ^.*$ $0.php [L] 
+0

взглянуть на этот http://serverfault.com/questions/720085/HTAccess-причины-бесконечномерная петля на лайве-сервере, но-работа-на-локальный хост – sammyukavi

Смежные вопросы