Jak działa RewriteBase w .htaccess

227

Widziałem to w kilku .htaccessprzykładach

RewriteBase /

Wygląda na nieco podobną funkcjonalnie do <base href="">HTML.

Wierzę, że może automatycznie przypisać swoją wartość do początku RewriteRuleinstrukcji (być może tych bez wiodącego ukośnika)?

Nie mogłem sprawić, żeby działał poprawnie. Myślę, że jego użycie może się przydać do przenoszenia stron, ponieważ często mam serwer programistyczny, który różni się od serwera produkcyjnego. Moja obecna metoda pozwala mi usuwać fragmenty ze swoich RewriteRulewyciągów.

Czy ktoś może mi krótko wyjaśnić, jak to wdrożyć?

Dzięki

alex
źródło
RewriteBase działa tylko w katalogu lub w kontekście .htaccess ... sprawdź kontekst pod podanym linkiem @SalmanPK.
Eddie B,
1
Zobacz tę odpowiedź, aby uzyskać dobry opis. stackoverflow.com/a/2137593/292060
goodeye
1
To jest bardziej szczegółowa odpowiedź: stackoverflow.com/a/21348047/632951
Pacerier
To jest odpowiedź 1-wierszowa: stackoverflow.com/a/46541685/632951
Pacerier

Odpowiedzi:

102

Moimi własnymi słowami, po przeczytaniu dokumentacji i eksperymentowaniu:

Możesz użyć, RewriteBaseaby zapewnić bazę dla swoich przeróbek. Rozważ to

# invoke rewrite engine
    RewriteEngine On
    RewriteBase /~new/

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

To jest prawdziwa zasada, której użyłem, aby upewnić się, że adresy URL mają ukośnik końcowy. To się skonwertuje

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

do

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

Mając RewriteBasetam, sprawiasz, że ścieżka względna nie odpowiada RewriteBaseparametrowi.

alex
źródło
10
„Wyjdź z parametru RewriteBase” - czy miałeś na myśli parametr rewriteRule? :)
Kissaki,
1
Chcę wyjaśnić niektóre szczegóły dotyczące htaccess .. czy ReWriteBase ustawia go dla wszystkich reguł w htaccess zgodnie z jego deklaracją? czy istnieje sposób, aby go rozbroić, czy można go zresetować?
Damon
3
@Kissaki: Nie, $1dopasowuje nawiasowy wzorzec RewriteRule, ale ścieżka względna podstawienia pochodzi z parametru RewriteBase. Tak więc wynikowe podstawienie to /~new/$1/.
MrWhite
3
@Damon: Zobacz to pytanie dotyczące wielu RewriteBasedyrektyw. Krótko mówiąc, nie możesz mieć więcej niż jednego - myślę, że ostatnia RewriteBase dyrektywa wygrywa i wpływa na cały plik .htaccess.
MrWhite
24
-1; ta odpowiedź wydaje się pomagać innym, ale jest dla mnie całkowicie nieprzejrzysta. Mogłem domyślić, że „można użyć RewriteBasew celu zapewnienia podstawy dla przepisuje” - to dość dużo tylko przegrupowanie słów - ale nie mam pojęcia, co to jest „baza” jest w tym kontekście, ani w jaki sens podany przykład byłby inny, gdyby RewriteBaselinia została usunięta. Przejdźmy do instrukcji idę ...
Mark Amery
89

RewriteBasejest stosowana tylko do tarczy o względnej reguła przepisywania.

  • Używanie RewriteBase w ten sposób ...

    RewriteBase /folder/
    RewriteRule a\.html b.html
    
  • jest zasadniczo taki sam jak ...

    RewriteRule a\.html /folder/b.html
    
  • Ale gdy plik .htaccess znajduje się w środku, oznacza /folder/to również ten sam cel:

    RewriteRule a\.html b.html
    

Chociaż dokumenty sugerują, że zawsze używa a RewriteBase, Apache zwykle wykrywa go poprawnie dla ścieżek w DocumentRoot, chyba że:

  • Używasz Aliasdyrektyw

  • Korzystasz z reguł przepisywania .htaccess do wykonywania przekierowań HTTP (zamiast po prostu cichego przepisywania) do względnych adresów URL

W takich przypadkach może się okazać, że musisz określić RewriteBase.

Ponieważ jednak jest to myląca dyrektywa, ogólnie lepiej jest po prostu określić bezwzględne (zwane też „względnymi rootami”) identyfikatory URI w obiektach do przepisywania. Inni programiści czytający twoje reguły łatwiej je zrozumieją.



Cytując doskonałą odpowiedź Jona Lin tutaj :

W pliku htaccess mod_rewrite działa podobnie do kontenera <Directory>lub <Location>. i RewriteBasesłuży do zapewnienia względnej podstawy ścieżki.

Załóżmy na przykład, że masz taką strukturę folderów:

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

Aby uzyskać dostęp do:

  • http://example.com/ (korzeń)
  • http://example.com/subdir1 (subdir1)
  • http://example.com/subdir2 (subdir2)
  • http://example.com/subdir2/subsubdir (subsubdir)

Identyfikator URI wysyłany przez a RewriteRulejest względny do katalogu zawierającego plik htaccess. Więc jeśli masz:

RewriteRule ^(.*)$ - 
  • W głównym htaccess, a żądanie jest /a/b/c/d, to przechwycony URI ( $1) jest a/b/c/d.
  • Jeśli reguła jest włączona, subdir2a żądanie jest, /subdir2/e/f/gto przechwycony identyfikator URI to e/f/g.
  • Jeśli reguła znajduje się w subsubdir, a żądanie jest /subdir2/subsubdir/x/y/z, to przechwycony identyfikator URI to x/y/z.

W katalogu, w którym znajduje się reguła, ta część jest pozbawiona identyfikatora URI. Baza przepisywania nie ma na to wpływu, po prostu działa na katalog.

Co baza przepisać ma zrobić, to stworzyć podstawy ścieżka_url ( nie bazie file-path) dla dowolnego względnych ścieżek w celu reguł można . Powiedzmy, że masz tę zasadę:

RewriteRule ^foo$ bar.php [L]

Jest bar.phpto ścieżka względna, w przeciwieństwie do:

RewriteRule ^foo$ /bar.php [L]

gdzie /bar.phpjest ścieżka absolutna. Ścieżką bezwzględną zawsze będzie „root” (w powyższej strukturze katalogów). Oznacza to, że niezależnie od tego, czy reguła znajduje się w katalogu „root”, „subdir1”, „subsubdir” itd., /bar.phpŚcieżka zawsze jest odwzorowywana http://example.com/bar.php.

Ale druga reguła, ze ścieżką względną, jest oparta na katalogu, w którym reguła się znajduje. Więc jeśli

RewriteRule ^foo$ bar.php [L]

jest w „katalogu głównym” i idziesz do http://example.com/foo, dostajesz obsłużony http://example.com/bar.php. Ale jeśli ta reguła znajduje się w katalogu „subdir1” i przejdziesz do http://example.com/subdir1/foo, zostaniesz obsłużony http://example.com/subdir1/bar.php. itp. Czasami to działa, a czasem nie, jak mówi dokumentacja, powinno być wymagane w przypadku ścieżek względnych, ale przez większość czasu wydaje się, że działa. Z wyjątkiem sytuacji, gdy przekierowujesz (używając Rflagi lub pośrednio, ponieważ masz http://hostw celu regułę). Oznacza to, że zasada:

RewriteRule ^foo$ bar.php [L,R]

jeśli jest w katalogu „subdir2” i udać się http://example.com/subdir2/foobędzie mod_rewrite pomylić ścieżkę względną jako pliku ścieżce zamiast ścieżka_url i ze względu na Rflagi, będziesz skończyć uzyskiwanie przekierowany na coś takiego: http://example.com/var/www/localhost/htdocs/subdir1. Co oczywiście nie jest tym, czego chcesz.

W tym miejscu RewriteBasepojawia się. Dyrektywa mówi mod_rewrite, co należy dołączyć na początku każdej ścieżki względnej. Więc jeśli mam:

RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]

w „subsubdir”, http://example.com/subdir2/subsubdir/foonaprawdę będzie mi służyć http://example.com/blah/bar.php. „Bar.php” jest dodawany na końcu bazy. W praktyce ten przykład zazwyczaj nie jest tym, czego potrzebujesz, ponieważ nie możesz mieć wielu baz w tym samym kontenerze katalogu lub pliku htaccess.

W większości przypadków jest on używany w następujący sposób:

RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]

gdzie reguły te znajdują się w katalogu „subdir1” i

RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]

będzie w katalogu „subsubdir”.

To częściowo pozwala uczynić twoje reguły przenośnymi, więc możesz upuścić je w dowolnym katalogu i wystarczy zmienić bazę zamiast kilku reguł. Na przykład, jeśli miałeś:

RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...

takich, które http://example.com/subdir1/foobędą służyć http://example.com/subdir1/bar.phpitp. Powiedzmy, że postanowiłeś przenieść wszystkie te pliki i reguły do ​​katalogu „subsubdir”. Zamiast zmieniać każdą instancję /subdir1/na /subdir2/subsubdir/, mógłbyś mieć po prostu bazę:

RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...

A kiedy musisz przenieść te pliki i reguły do ​​innego katalogu, po prostu zmień bazę:

RewriteBase /subdir2/subsubdir/

i to wszystko.

Simon East
źródło
Dla mnie tęskniłem RewriteEngine On. Na przykład nie potrzebujesz 1 i 1, ale jest to wymagane na moim serwerze dedykowanym.
Portekoi,
41

AFAIK, RewriteBase służy tylko do naprawiania przypadków, w których mod_rewrite działa w .htaccesspliku, który nie znajduje się w katalogu głównym witryny, i zgaduje niewłaściwą ścieżkę sieciową (w przeciwieństwie do ścieżki systemu plików) dla folderu, w którym działa. Więc jeśli masz RewriteRule w pliku .htaccess w folderze, który jest mapowany http://example.com/myfolder, możesz użyć:

RewriteBase myfolder

Jeśli mod_rewrite nie działa poprawnie.

Próba użycia go do osiągnięcia czegoś niezwykłego, zamiast rozwiązania tego problemu, brzmi jak przepis na bardzo zagubiony.

rjmunro
źródło
2
Czy musi kończyć się ukośnikiem?
Pacerier
@self, No. Testowany i opisany poniżej: stackoverflow.com/a/11443194/632951
Pacerier
23

RewriteBase jest użyteczny tylko w sytuacjach, w których możesz umieścić .htaccess tylko w katalogu głównym swojej witryny. W przeciwnym razie lepiej będzie, jeśli umieścisz różne pliki .htaccess w różnych katalogach witryny i całkowicie pominiesz dyrektywę RewriteBase.

Ostatnio, w przypadku złożonych witryn, usuwam je, ponieważ komplikuje wdrażanie plików z testów do życia o jeszcze jeden krok.

Thomas Hunter II
źródło
22
Chociaż może to być dobra rada, wcale nie jest to odpowiedź na pytanie. Powinien zatem być komentarzem do pytania, nie otrzymał (tylu) pozytywnych opinii i zdecydowanie nie został zaakceptowany jako „odpowiedź”.
Kissaki,
3
„lepiej umieścić swoje różne pliki .htaccess w różnych katalogach” - nie jestem pewien, czy to dobra rada? Rozrzucanie plików .htaccess w całej witrynie może sprawić, że debugowanie / konserwacja stanie się koszmarem. Powiedziałbym, że lepiej jest mieć jeden plik .htaccess w katalogu głównym witryny.
MrWhite
1
@ w3d Istnieje również kwestia czasu: za każdym razem, gdy uzyskuje się dostęp do podkatalogu, parsowanych jest wiele plików .htaccess (od katalogu głównego do bieżącego podkatalogu). Posiadanie dużej liczby plików może obniżyć szybkość ogólnej odpowiedzi na żądanie, w przeciwieństwie do pojedynczego pliku w katalogu głównym, nawet jeśli zawiera wiele reguł.
Erenor Paz
19

Kiedy się rozwijam, znajduje się w innej domenie w folderze. Kiedy uruchamiam witrynę na żywo, ten folder już nie istnieje. Korzystanie z RewriteBase pozwala mi używać tego samego pliku .htaccess w obu środowiskach.

Kiedy na żywo:

RewriteBase /
# RewriteBase /dev_folder/

Podczas opracowywania:

# RewriteBase /
RewriteBase /dev_folder/
użytkownik1669830
źródło
4
Jestem pewien, że to nie zawsze zadziała. Co jeśli użyto %{REQUEST_URI}w RewriteConddyrektywie na przykład?
MrWhite
1
@ user1669830, Jeśli masz tylko jedno RewriteRule, mogłeś po prostu dodaje się do bazy RewriteRule stackoverflow.com/a/46541685/632951
Pacerier
18

Najjaśniejsze wyjaśnienie, które znalazłem, nie było w aktualnych dokumentach apache 2.4, ale w wersji 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

Jak to działa? Dla hakerów apache ten dokument 2.0 podaje „szczegółowe informacje na temat wewnętrznych kroków przetwarzania”.

Wyciągnięta lekcja: Chociaż musimy być zaznajomieni z „prądem”, klejnoty można znaleźć w annałach.

DWB
źródło
3

To polecenie może jawnie ustawić podstawowy adres URL dla twoich przeróbek. Jeśli chcesz zacząć od katalogu głównego swojej domeny, dołącz swój wiersz przed RewriteRule:

RewriteBase /
Sandeep Goyal
źródło
2

Uważam, że ten fragment dokumentacji Apache dobrze uzupełnia poprzednie odpowiedzi:

Ta dyrektywa jest wymagana, jeśli używasz ścieżki względnej w podstawieniu w kontekście dla katalogu (htaccess), chyba że spełniony jest jeden z następujących warunków:

  • Pierwotne żądanie i podstawienie znajdują się pod DocumentRoot (w przeciwieństwie do osiągalnego za pomocą innych środków, takich jak Alias).

  • Ścieżka systemu plików do katalogu zawierającego RewriteRule, z przyrostkiem względnym podstawienia, jest również poprawna jako ścieżka adresu URL na serwerze (jest to rzadkie).

Jak wspomniano wcześniej, w innych kontekstach przydatne jest jedynie skrócenie reguły. Co więcej, jak wspomniano wcześniej, możesz to samo osiągnąć, umieszczając plik htaccess w podkatalogu.

alex
źródło