Что делает RewriteBase и как его использовать?
Я пытаюсь выучить .htaccess
трюки. Я наткнулся на RewriteBase
директива, но не может заставить его работать должным образом.
Интересно, что конкретно делает эта директива и как ее использовать. Там были некоторые дискуссии о RewriteBase
в Stackru и документации Apache, но все же я не смог получить четкий ответ на свой вопрос.
Может ли кто-нибудь показать мне простой, но эффективный пример, где RewriteBase
может быть использован?
2 ответа
В файле htaccess mod_rewrite работает аналогично <Directory>
или же <Location>
контейнер. и RewriteBase
используется для обеспечения базы относительного пути.
Например, скажем, у вас есть эта структура папок:
root
|-- subdir1
|-- subdir2
|-- subsubdir
Таким образом, вы можете получить доступ к:
http://example.com/
(Корень)http://example.com/subdir1
(Subdir1)http://example.com/subdir2
(Subdir2)http://example.com/subdir2/subsubdir
(Subsubdir)
URI, который отправляется через RewriteRule
относительно каталога. Так что если у вас есть:
RewriteRule ^(.*)$ -
в корне, а запрос /a/b/c/d
затем захваченный URI ($1
) является a/b/c/d
, Но если правило в subdir2
и запрос /subdir2/e/f/g
тогда захваченный URI e/f/g
, И если правило в subsubdir
и запрос /subdir2/subsubdir/x/y/z
то захваченный URI x/y/z
, В каталоге, в котором находится правило, эта часть удалена из URI. База переписывания не влияет на это, это просто, как работает для каждого каталога.
Что делает база перезаписи, так это предоставляет базу URL-путей (не базу файловых путей) для любых относительных путей в целевом объекте правила. Скажем так, у вас есть это правило:
RewriteRule ^foo$ bar.php [L]
bar.php
это относительный путь, в отличие от:
RewriteRule ^foo$ /bar.php [L]
где /bar.php
это абсолютный путь. Абсолютный путь всегда будет "корневым" (в структуре каталогов выше). Это означает, что если правило находится в "root", "subdir1", "subsubdir" и т. Д. /bar.php
путь всегда отображается на http://example.com/bar.php
,
Но другое правило, с относительным путем, оно основано на каталоге, в котором находится правило. Так что если
RewriteRule ^foo$ bar.php [L]
находится в "корне", и вы идете http://example.com/foo
, ты обслужен http://example.com/bar.php
, Но если это правило находится в каталоге "subdir1", и вы переходите к http://example.com/subdir1/foo
, ты обслужен http://example.com/subdir1/bar.php
, и т. д. Иногда это работает, а иногда нет, как говорится в документации, это требуется для относительных путей, но в большинстве случаев это работает. За исключением случаев, когда вы перенаправляете (используя R
флаг, или неявно, потому что у вас есть http://host
в цель вашего правила). Это означает, что это правило:
RewriteRule ^foo$ bar.php [L,R]
если он находится в каталоге "subdir2", и вы идете в http://example.com/subdir2/foo
mod_rewrite будет ошибочно принимать относительный путь как путь к файлу вместо URL-пути и из-за R
флаг, в итоге вы будете перенаправлены на что-то вроде: http://example.com/var/www/localhost/htdocs/subdir1
, Что, очевидно, не то, что вы хотите.
Это где RewriteBase
входит. Директива сообщает mod_rewrite, что добавлять в начало каждого относительного пути. Так что если у меня есть:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
и это правило находится в "Sububdir", собирается http://example.com/subdir2/subsubdir/foo
на самом деле будет служить мне http://example.com/blah/bar.php
, "Bar.php" добавляется в конец базы. На практике этот пример обычно не тот, который вам нужен, потому что вы не можете иметь несколько баз в одном контейнере каталога или файле htaccess.
В большинстве случаев он используется так:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
где эти правила будут в каталоге "subdir1" и
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
будет в каталоге "subsubdir".
Это частично позволяет вам сделать ваши правила переносимыми, так что вы можете удалить их в любом каталоге, и вам нужно всего лишь изменить базу вместо набора правил. Например, если у вас было:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
такой, что собирается http://example.com/subdir1/foo
будет служить http://example.com/subdir1/bar.php
и т.д. И скажем, вы решили переместить все эти файлы и правила в каталог subsubdir. Вместо того, чтобы менять каждый экземпляр /subdir1/
в /subdir2/subsubdir/
, вы могли бы просто иметь базу:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
И затем, когда вам нужно было переместить эти файлы и правила в другой каталог, просто измените базу:
RewriteBase /subdir2/subsubdir/
и это все.
Ответ в 1 строке: Rewritebase устанавливает базовый путь rewriterule arg2.
Это буквально это. (поэтому он работает как html basehref, ⨕ за исключением того, что он полезен, так как часто в контексте перезаписи URL базы по умолчанию [ .
] не требуется.)
Rewritebase упрощает обслуживание, если у вас есть несколько rewriterules. Действительно, если вы используете только одну строку rewriterule, тогда rewritebase практически бесполезен (так как вы можете просто переписать основанный URL).
Примечание
Конечно, вы можете полностью игнорировать rewritebase, используя только абсолютные пути для rewriterules.
связанные с
RewriteBase
позволяет настроить путь, который mod_rewrite
автоматически добавляет префиксы к результату RewriteRule
. Перезапись в контексте.htaccess выполняется относительно каталога, содержащего этот файл.htaccess. Непосредственный результат RewriteRule по-прежнему относится к каталогу, содержащему файл.htaccess, но mod_rewrite затем корректирует этот результат, делая его вместо этого относительно корня документа.RewriteBase
позволяет вам изменить этот последний шаг, позволяя указать произвольный базовый путь, который добавляется к непосредственному результату RewriteRule, вместо корня документа.
Для меня ключевым моментом понимания RewriteBase
директива, когда я понял, что mod_rewrite применяется RewriteBase
результаты изRewriteRules
, а не их аргументам.
Нормальная обработка RewriteRule
в контексте файла.htaccess выглядит так:
- Создайте запрошенный путь относительно каталога, содержащего файл.htaccess. Если, например, URI - https://www.example.com/one/two/three, а файл.htaccess имеет путь
/doc_root/one/.htaccess
, то сгенерированный путь будет/two/three
. - Затем RewriteRules перезаписывают относительный путь сверху.
- Префикс полученного перезаписанного пути выше с полным путем файловой системы к файлу.htaccess
- Удалите путь к корню документа с начала перезаписанного пути выше.
Этот процесс приводит к перезаписи пути относительно корня документа.
Когда есть RewriteBase
директиве, шаги 1,2 и 3 остаются прежними, изменяется только шаг 4. Вместо корня документа удаляется путь файловой системы к каталогу, содержащему файл.htaccess. ЗатемRewriteBase
добавляется.
Пример:
- Запрос -
https://example.com/one/two/three/file.txt
- Корень документа -
/var/doc_root
- Расположение htaccess -
/var/doc_root/one/.htaccess
- RewriteBase -
/var/other_location/
Без RewriteBase в файле htaccess это обрабатывается как:
- Получить часть запрошенного пути относительно htaccess -
/two/three/file.txt
- Сделайте переписывание -
/four/rewritten.txt
- Добавьте путь к файлу.htaccess -
/var/do_root/one/four/rewritten.txt
- Удалите корень документа -
one/four/rewritten.txt
С помощью RewriteBase в файле.htaccess это обрабатывается как:
- Получить часть запрошенного пути относительно htaccess -
/two/three/file.txt
- Сделайте переписывание -
/four/rewritten.txt
- Подготовьте RewriteBase -
/var/other_location/four/rewritten.txt