Як працює RewriteBase в .htaccess


227

Я це бачив на кількох .htaccessприкладах

RewriteBase /

Він, схоже, за функціоналом схожий на <base href="">HTML.

Я вважаю, що він може автоматично додати своє значення до початку RewriteRuleвисловлювань (можливо, тих, що не мають прорізної риски)?

Я не міг змусити його нормально працювати. Я думаю, що його використання може стати дуже зручним для портативності сайтів, оскільки у мене часто є сервер розробки, який відрізняється від виробничого. Мій поточний метод дозволяє мені видаляти частини з моїх RewriteRuleзаяв.

Хтось може мені коротко пояснити, як це здійснити?

Дякую



RewriteBase працює лише в каталозі або .htaccess контексті ... зверніться до контексту за посиланням @SalmanPK, що надається.
Едді Б

1
Дивіться цю відповідь для гарного опису. stackoverflow.com/a/2137593/292060
goodeye

1
Це більш поглибленого відповіді: stackoverflow.com/a/21348047/632951
Pacerier

Це 1-лінія Відповідь: stackoverflow.com/a/46541685/632951
Pacerier

Відповіді:


102

З моїх власних слів, прочитавши документи та експериментуючи:

Ви можете використовувати , RewriteBaseщоб забезпечити основу для ваших переписує. Розглянемо це

# invoke rewrite engine
    RewriteEngine On
    RewriteBase /~new/

# add trailing slash if missing
    rewriteRule ^(([a-z0-9\-]+/)*[a-z0-9\-]+)$ $1/ [NC,R=301,L]

Це справжнє правило, яке я використовував для того, щоб URL-адреси мали прорізну косу рису. Це перетворить

http://www.example.com/~new/page

до

http://www.example.com/~new/page/

Маючи RewriteBaseтам, ви робите відносний шлях виходу з RewriteBaseпараметра.


10
“Зійти з параметра RewriteBase” - ти мав на увазі параметр rewriteRule? :)
Кіссакі

1
Я хочу прояснити деякі подробиці про htaccess .. чи ReWriteBase встановлює його для всіх правил у htaccess, слідуючи за його декларацією? чи є спосіб її зняти, чи можна її скинути?
Деймон

3
@Kissaki: Ні, $1відповідає збірному круглому шаблону RewriteRule, але відносний шлях заміни виходить із параметра RewriteBase. Отже, отримана підміна є /~new/$1/.
MrWhite

3
@Damon: Дивіться це питання стосовно кількох RewriteBaseдиректив. Коротше кажучи, ви не можете мати більше одного - я думаю, що остання RewriteBase директива перемагає і впливає на весь файл .htaccess.
MrWhite

24
-1; ця відповідь, здається, допомагала іншим, але для мене абсолютно непрозора. Я міг би здогадатися , що «Ви можете використовувати , RewriteBaseщоб забезпечити основу для переписування» - це в значній мірі просто перестановка слів - але я поняття не маю , що таке «база» знаходиться в цьому контексті, ні те, як сенс приклад, який ви подали, відрізнятиметься, якби RewriteBaseрядок було видалено. Перейти до посібника, який я йду ...
Марк Амерді

89

RewriteBaseзастосовується тільки до мішені про наявність відносного правила перезапису.

  • Використовуючи RewriteBase, як це ...

    RewriteBase /folder/
    RewriteRule a\.html b.html
    
  • по суті те саме, що ...

    RewriteRule a\.html /folder/b.html
    
  • Але коли файл .htaccess знаходиться всередині, /folder/то це також вказує на ту саму ціль:

    RewriteRule a\.html b.html
    

Хоча документи завжди мають на увазі використання A RewriteBase, Apache зазвичай правильно його виявляє для шляхів під DocumentRoot, якщо:

  • Ви використовуєте Aliasдирективи

  • Ви використовуєте правила перезапису .htaccess для виконання переспрямувань HTTP (а не просто тихого переписування) до відносних URL-адрес

У цих випадках ви можете виявити, що вам потрібно вказати RewriteBase.

Однак, оскільки це заплутана директива, як правило, краще просто вказати абсолютні (також "кореневі відносні") URI у ваших цілях перезапису. Інші розробники, які читають ваші правила, зрозуміють їх легше.



Цитуючи чудову глибоку відповідь Джона Ліна тут :

У файлі htaccess mod_rewrite працює аналогічно до <Directory>або <Location>контейнера. і RewriteBaseвикористовується для забезпечення відносної бази шляху.

Наприклад, скажіть, що у вас є така структура папок:

DocumentRoot
|-- subdir1
`-- subdir2
    `-- subsubdir

Таким чином, ви можете отримати доступ:

  • http://example.com/ (корінь)
  • http://example.com/subdir1 (subdir1)
  • http://example.com/subdir2 (subdir2)
  • http://example.com/subdir2/subsubdir (sububdir)

URI, який надсилається через a 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]

в "subsubdir", збираюся 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/

і це все.


Для мене я сумував RewriteEngine On. Наприклад, немає потреби в 1and1, але це потрібно на моєму виділеному сервері.
Портекой

41

AFAIK, RewriteBase використовується лише для виправлення випадків, коли mod_rewrite працює у .htaccessфайлі не в корені сайту, і він здогадується про неправильний веб-шлях (на відміну від шляху до файлової системи) для папки, в якій він працює. Отже, якщо у вас є Перезапишіть у .htaccess у папці, яка відображає http://example.com/myfolderвас, ви можете використовувати:

RewriteBase myfolder

Якщо mod_rewrite працює неправильно

Намагання використовувати його для досягнення чогось незвичного, а не для вирішення цієї проблеми, звучить як рецепт, щоб дуже заплутатися.


2
Чи потрібно це закінчувати косою косою рисою?
Печер'є

@self, № випробувано, і до півдня пояснюється тут: stackoverflow.com/a/11443194/632951
Pacerier

23

RewriteBase корисний лише в ситуаціях, коли ви можете розмістити .htaccess у корені вашого сайту. Інакше вам може бути краще розмістити різні файли .htaccess у різних каталогах вашого сайту та повністю пропустити директиву RewriteBase.

Останнім часом для складних сайтів я виймаю їх, оскільки це ускладнює розгортання файлів із тестування, щоб жити ще один крок.


22
Хоча це може бути гарною порадою, це зовсім не відповідь на питання. Таким чином, він повинен бути коментарем до цього питання, не отримав (як багато) оновлень і, безумовно, не був прийнятий як "відповідь".
Кіссакі

3
"краще розміщувати різні файли .htaccess в різних каталогах" - я не впевнений, що це хороша порада? Файли .htaccess, нанесені крапками по всьому сайту, можуть налагодити / підтримувати кошмар. Я б сказав, що краще мати один .htaccess файл у корені вашого сайту.
MrWhite

1
@ w3d Є також питання про терміни: кожен раз, коли є доступ до підкаталогу, розбираються декілька файлів .htaccess (від кореня до поточного підкаталогу). Маючи багато файлів, можна знизити швидкість загальної відповіді на запит, на відміну від одного файлу в корені, навіть якщо він містить багато правил ..
Еренор Паз,

19

Коли я розробляю, він знаходиться в іншому домені в межах папки. Коли я беру сайт наживо, ця папка вже не існує. Використання RewriteBase дозволяє мені використовувати один і той же файл .htaccess в обох середовищах.

Коли живе:

RewriteBase /
# RewriteBase /dev_folder/

При розробці:

# RewriteBase /
RewriteBase /dev_folder/

4
Я впевнений, що це не завжди вийде. Що робити , якщо ви використовували %{REQUEST_URI}в RewriteCondдирективі, наприклад?
MrWhite

1
@ User1669830, якщо у вас є тільки один RewriteRule, ви могли б просто додали підставу до RewriteRule stackoverflow.com/a/46541685/632951
Pacerier

18

Ясніше пояснення, яке я знайшов, було не в нинішніх документах 2.4 apache, а у версії 2.0 .

#  /abc/def/.htaccess -- per-dir config file for directory /abc/def
#  Remember: /abc/def is the physical path of /xyz, i.e., the server
#            has a 'Alias /xyz /abc/def' directive e.g.

RewriteEngine On

#  let the server know that we were reached via /xyz and not
#  via the physical path prefix /abc/def
RewriteBase   /xyz

Як це працює? Для ваших хакерів apache цей документ 2.0 надає "детальну інформацію про внутрішні кроки обробки".

Занятий урок: Хоча нам потрібно ознайомитись із "поточними", дорогоцінні камені можна знайти в літописі.


3

Ця команда може явно встановити базову URL-адресу для ваших переписувачів. Якщо ви хочете почати в корені свого домену, перед вашим RewriteRule слід включити наступний рядок:

RewriteBase /

2

Я вважаю, що цей уривок із документації Apache добре доповнює попередні відповіді:

Ця директива потрібна, коли ви використовуєте відносний шлях для заміни в контексті per-directory (htaccess), якщо не виконується жодне з наступних умов:

  • Оригінальний запит і заміна знаходяться під DocumentRoot (на відміну від доступного іншими способами, наприклад, псевдонімом).

  • Шлях файлової системи до каталогу, що містить RewriteRule, суфікс відносної заміни, також дійсний як шлях до URL на сервері (це рідко).

Як було сказано раніше, в інших контекстах корисно лише скоротити своє правило. Більше того, як уже згадувалося раніше, ви можете досягти того ж, розмістивши файл htaccess у підкаталозі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.