RewriteBase
применяется только к цели из относительно правила перезаписи.
Использование RewriteBase, как это ...
RewriteBase /folder/
RewriteRule a\.html b.html
по сути то же самое, что и ...
RewriteRule a\.html /folder/b.html
Но если файл .htaccess находится внутри /folder/
, то это также указывает на ту же цель:
RewriteRule a\.html b.html
Хотя в документах всегда используется RewriteBase
, Apache обычно правильно определяет его для путей в DocumentRoot, если:
В этих случаях может потребоваться указать RewriteBase.
Однако, поскольку это непонятная директива, обычно лучше просто указывать абсолютные (иначе называемые «коренные родственники») URI в ваших целях перезаписи. Другие разработчики, читающие ваши правила, поймут это легче.
Цитата из Отличный исчерпывающий ответ Джона Линя здесь :
В файле htaccess mod_rewrite работает аналогично контейнеру <Directory>
или <Location>
. и RewriteBase
используется для обеспечения базы относительного пути.
Например, скажем, у вас есть такая структура папок:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
Таким образом, вы можете получить доступ:
URI, который отправляется через RewriteRule
, относится к каталогу, содержащему файл htaccess. Так что если у вас есть:
RewriteRule ^(.*)$ -
- В корне htaccess и запросом является
/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]
будет в каталоге "sububdir".
Это частично позволяет вам сделать ваши правила переносимыми, так что вы можете удалить их в любой каталог, и вам нужно всего лишь изменить базу вместо набора правил. Например, если у вас было:
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/
и все.