Wie funktioniert RewriteBase in .htaccess?

227

Ich habe dies in einigen .htaccessBeispielen gesehen

RewriteBase /

Die Funktionalität scheint der <base href="">von HTML etwas ähnlich zu sein .

Ich glaube, es kann seinen Wert automatisch an den Anfang von RewriteRuleAussagen stellen (möglicherweise solche ohne führenden Schrägstrich)?

Ich konnte es nicht richtig zum Laufen bringen. Ich denke, die Verwendung könnte für die Portabilität von Websites sehr nützlich sein, da ich häufig einen Entwicklungsserver habe, der sich von einem Produktionsserver unterscheidet. Bei meiner aktuellen Methode lösche ich Teile aus meinen RewriteRuleAnweisungen.

Kann mir jemand kurz erklären, wie man es umsetzt?

Vielen Dank

Alex
quelle
RewriteBase funktioniert nur im Verzeichnis- oder .htaccess-Kontext. Den angegebenen Link @SalmanPK finden Sie im Kontext.
Eddie B
1
In dieser Antwort finden Sie eine gute Beschreibung. stackoverflow.com/a/2137593/292060
goodeye
1
Dies ist eine ausführlichere Antwort: stackoverflow.com/a/21348047/632951
Pacerier
Dies ist eine 1-zeilige Antwort: stackoverflow.com/a/46541685/632951
Pacerier

Antworten:

102

In meinen eigenen Worten, nachdem ich die Dokumente gelesen und experimentiert habe:

Sie können verwenden RewriteBase, um eine Basis für Ihre Umschreibungen bereitzustellen . Bedenken Sie

# invoke rewrite engine
    RewriteEngine On
    RewriteBase /~new/

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

Dies ist eine echte Regel, die ich verwendet habe, um sicherzustellen, dass URLs einen abschließenden Schrägstrich haben. Dies wird konvertieren

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

zu

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

Wenn Sie das RewriteBasedort haben, wird der relative Pfad vom RewriteBaseParameter entfernt.

Alex
quelle
10
"Verlassen Sie den RewriteBase-Parameter" - meinten Sie den rewriteRule-Parameter? :)
Kissaki
1
Ich möchte einige Details zu htaccess klären. Setzt eine ReWriteBase sie für alle Regeln im htaccess nach ihrer Deklaration? Gibt es eine Möglichkeit, es zu deaktivieren? Kann es zurückgesetzt werden?
Damon
3
@Kissaki: Nein, das $1entspricht dem in Klammern gesetzten RewriteRule-Muster, aber der relative Pfad für die Substitution ergibt sich aus dem RewriteBase-Parameter. Die resultierende Substitution ist also /~new/$1/.
MrWhite
3
@Damon: Siehe diese Frage zu mehreren RewriteBaseDirektiven. Kurz gesagt, Sie können nicht mehr als eine haben - ich denke, die letzte RewriteBase Direktive gewinnt und wirkt sich auf die gesamte .htaccess-Datei aus.
MrWhite
24
-1; Diese Antwort scheint anderen geholfen zu haben, ist aber für mich völlig undurchsichtig. Ich habe gedacht , dass „Sie verwenden können , um RewriteBaseeine Basis für Ihre Neufassungen zu schaffen“ - die nur eine Umordnung der Worte ziemlich sind - aber ich habe keine Ahnung , was für eine „Basis“ ist in diesem Zusammenhang noch , wie die Bedeutung der Das von Ihnen angegebene Beispiel würde sich unterscheiden, wenn die RewriteBaseZeile entfernt würde. Auf zum Handbuch gehe ich ...
Mark Amery
89

RewriteBasewird nur auf das Ziel einer relativen Umschreiberegel angewendet .

  • Verwenden Sie RewriteBase wie folgt ...

    RewriteBase /folder/
    RewriteRule a\.html b.html
    
  • ist im Wesentlichen das gleiche wie ...

    RewriteRule a\.html /folder/b.html
    
  • Wenn sich die .htaccess-Datei jedoch befindet, zeigt /folder/dies auch auf dasselbe Ziel:

    RewriteRule a\.html b.html
    

Obwohl die Dokumente implizieren, dass immer a verwendet wird RewriteBase, erkennt Apache es normalerweise korrekt für Pfade unter DocumentRoot, es sei denn:

  • Sie verwenden AliasDirektiven

  • Sie verwenden .htaccess-Umschreiberegeln, um HTTP-Umleitungen (und nicht nur stilles Umschreiben) zu relativen URLs durchzuführen

In diesen Fällen müssen Sie möglicherweise die RewriteBase angeben.

Da es sich jedoch um eine verwirrende Direktive handelt, ist es im Allgemeinen besser, absolute (auch als "root relative" bezeichnete) URIs in Ihren Umschreibungszielen anzugeben. Andere Entwickler, die Ihre Regeln lesen, werden diese leichter verstehen.



Zitat aus Jon Lins ausgezeichneter ausführlicher Antwort hier :

In einer htaccess-Datei funktioniert mod_rewrite ähnlich wie ein <Directory>oder <Location>container. und das RewriteBasewird verwendet, um eine relative Pfadbasis bereitzustellen.

Angenommen, Sie haben diese Ordnerstruktur:

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

So können Sie zugreifen:

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

Der URI, der über a gesendet RewriteRulewird, bezieht sich auf das Verzeichnis, das die htaccess-Datei enthält. Also, wenn Sie haben:

RewriteRule ^(.*)$ - 
  • Im root htaccess und die Anfrage ist /a/b/c/d, dann ist der erfasste URI ( $1) a/b/c/d.
  • Wenn die Regel aktiviert ist subdir2und die Anforderung lautet, lautet /subdir2/e/f/gder erfasste URI e/f/g.
  • Wenn sich die Regel in der subsubdirbefindet und die Anforderung lautet /subdir2/subsubdir/x/y/z, lautet der erfasste URI x/y/z.

In dem Verzeichnis, in dem sich die Regel befindet, wird dieser Teil von der URI entfernt. Die Umschreibbasis hat keinen Einfluss darauf. So funktioniert das Verzeichnis einfach.

Was die Rewrite - Basis nicht tun, ist es, eine URL-Pfad Basis bereitstellen ( nicht eine Datei-Pfad - Basis) für alle relativen Pfade in der Ziel-Regel . Angenommen, Sie haben diese Regel:

RewriteRule ^foo$ bar.php [L]

Das bar.phpist ein relativer Pfad im Gegensatz zu:

RewriteRule ^foo$ /bar.php [L]

wo das /bar.phpein absoluter Weg ist. Der absolute Pfad ist immer der "Stamm" (in der obigen Verzeichnisstruktur). Dies bedeutet, dass unabhängig davon, ob sich die Regel im "root", "subdir1", "subsubdir" usw. befindet, der /bar.phpPfad immer zugeordnet ist http://example.com/bar.php.

Die andere Regel mit dem relativen Pfad basiert jedoch auf dem Verzeichnis, in dem sich die Regel befindet

RewriteRule ^foo$ bar.php [L]

ist in der "Wurzel" und du gehst zu http://example.com/foo, du wirst bedient http://example.com/bar.php. Wenn sich diese Regel jedoch im Verzeichnis "subdir1" befindet und Sie zu gehen http://example.com/subdir1/foo, werden Sie bedient http://example.com/subdir1/bar.php. usw. Dies funktioniert manchmal und manchmal nicht, wie in der Dokumentation angegeben, für relative Pfade erforderlich , aber die meiste Zeit scheint es zu funktionieren. Außer wenn Sie umleiten (mithilfe des RFlags oder implizit, weil Sie http://hostdas Ziel Ihrer Regel haben). Das heißt diese Regel:

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

Wenn es sich im Verzeichnis "subdir2" befindet und Sie zu gehen http://example.com/subdir2/foo, verwechselt mod_rewrite den relativen Pfad als Dateipfad anstelle eines URL-Pfads. Aufgrund des RFlags werden Sie am Ende auf Folgendes umgeleitet : http://example.com/var/www/localhost/htdocs/subdir1. Welches ist offensichtlich nicht das, was Sie wollen.

Hier RewriteBasekommt der Befehl ins Spiel. Die Direktive teilt mod_rewrite mit, was an den Anfang jedes relativen Pfads angehängt werden soll. Also wenn ich habe:

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

in "subsubdir" http://example.com/subdir2/subsubdir/foowird mir das eigentlich dienen http://example.com/blah/bar.php. Die "bar.php" wird am Ende der Basis hinzugefügt. In der Praxis ist dieses Beispiel normalerweise nicht das, was Sie wollen, da Sie nicht mehrere Basen im selben Verzeichniscontainer oder in derselben htaccess-Datei haben können.

In den meisten Fällen wird es folgendermaßen verwendet:

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

wo sich diese Regeln im Verzeichnis "subdir1" befinden würden und

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

wäre im "subsubdir" -Verzeichnis.

Auf diese Weise können Sie Ihre Regeln teilweise portabel machen, sodass Sie sie in einem beliebigen Verzeichnis ablegen können und nur die Basis anstelle einer Reihe von Regeln ändern müssen. Zum Beispiel, wenn Sie hatten:

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

so dass zu gehen http://example.com/subdir1/foodienen http://example.com/subdir1/bar.phpetc. Und sagen Sie beschlossen, alle diese Dateien und Regeln zum „subsubdir“ Verzeichnis. Anstatt jede Instanz von /subdir1/to zu ändern /subdir2/subsubdir/, hätten Sie einfach eine Basis haben können:

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

Und wenn Sie diese Dateien und Regeln in ein anderes Verzeichnis verschieben mussten, ändern Sie einfach die Basis:

RewriteBase /subdir2/subsubdir/

und das ist es.

Simon East
quelle
Für mich habe ich vermisst RewriteEngine On. Zum Beispiel keine Notwendigkeit für 1 und 1, aber für meinen dedizierten Server.
Portekoi
41

AFAIK, RewriteBase wird nur verwendet, um Fälle zu beheben, in denen mod_rewrite in einer .htaccessDatei ausgeführt wird, die sich nicht im Stammverzeichnis einer Site befindet, und der falsche Webpfad (im Gegensatz zum Dateisystempfad) für den Ordner erraten wird, in dem er ausgeführt wird RewriteRule in einem .htaccess in einem Ordner, der http://example.com/myfolderIhnen zugeordnet ist, kann Folgendes verwenden:

RewriteBase myfolder

Wenn mod_rewrite nicht richtig funktioniert.

Der Versuch, damit etwas Ungewöhnliches zu erreichen, anstatt dieses Problem zu beheben, klingt nach einem Rezept, um sehr verwirrt zu werden.

rjmunro
quelle
2
Muss es mit einem abschließenden Schrägstrich enden?
Pacerier
@self, No. Getestet und hier unten
Pacerier
23

RewriteBase ist nur in Situationen nützlich, in denen Sie einen .htaccess nur im Stammverzeichnis Ihrer Site platzieren können. Andernfalls ist es möglicherweise besser, Ihre verschiedenen .htaccess-Dateien in verschiedenen Verzeichnissen Ihrer Site abzulegen und die RewriteBase-Direktive vollständig wegzulassen.

In letzter Zeit habe ich komplexe Websites entfernt, da dadurch die Bereitstellung von Dateien vom Testen zum Leben nur noch einen Schritt komplizierter wird.

Thomas Hunter II
quelle
22
Obwohl dies ein guter Rat sein mag, ist dies überhaupt keine Antwort auf die Frage. Es hätte also ein Kommentar zu der Frage sein sollen, nicht (so viele) positive Stimmen erhalten und definitiv nicht als „Antwort“ akzeptiert werden sollen.
Kissaki
3
"Besser dran, Ihre verschiedenen .htaccess-Dateien in verschiedenen Verzeichnissen abzulegen" - Ich bin mir nicht sicher, ob dies ein guter Rat ist? Wenn .htaccess-Dateien auf Ihrer Website verteilt sind, kann das Debuggen / Warten zu einem Albtraum werden. Ich hätte gesagt, es wäre vorzuziehen , eine .htaccess-Datei im Stammverzeichnis Ihrer Site zu haben.
MrWhite
1
@ w3d Es gibt auch eine zeitliche Frage: Bei jedem Zugriff auf ein Unterverzeichnis werden mehrere .htaccess-Dateien analysiert (vom Stammverzeichnis zum aktuellen Unterverzeichnis). Viele Dateien können die Geschwindigkeit der Gesamtantwort auf die Anfrage
verringern
19

Wenn ich entwickle, befindet es sich in einer anderen Domäne innerhalb eines Ordners. Wenn ich eine Site live nehme, existiert dieser Ordner nicht mehr. Mit RewriteBase kann ich in beiden Umgebungen dieselbe .htaccess-Datei verwenden.

Wenn live:

RewriteBase /
# RewriteBase /dev_folder/

Bei der Entwicklung:

# RewriteBase /
RewriteBase /dev_folder/
user1669830
quelle
4
Ich bin sicher, dass dies nicht immer funktionieren wird. Was ist, wenn Sie zum Beispiel %{REQUEST_URI}in einer RewriteCondDirektive verwendet haben?
MrWhite
1
@ user1669830, Wenn Sie nur eine Umschreibung haben, könnten Sie einfach die Basis zur Umschreibung Stackoverflow.com/a/46541685/632951
Pacerier
18

Die klarste Erklärung, die ich gefunden habe, war nicht in den aktuellen Apache-Dokumenten 2.4, sondern in Version 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

Wie funktioniert es? Für Sie Apache-Hacker enthält dieses 2.0-Dokument "detaillierte Informationen zu den internen Verarbeitungsschritten".

Lektion gelernt: Während wir mit "aktuell" vertraut sein müssen, finden sich Edelsteine ​​in den Annalen.

DWB
quelle
3

Dieser Befehl kann die Basis-URL für Ihre Umschreibungen explizit festlegen. Wenn Sie im Stammverzeichnis Ihrer Domain beginnen möchten, fügen Sie vor Ihrer RewriteRule die folgende Zeile ein:

RewriteBase /
Sandeep Goyal
quelle
2

Ich glaube, dieser Auszug aus der Apache-Dokumentation ergänzt die vorherigen Antworten gut:

Diese Anweisung ist erforderlich, wenn Sie einen relativen Pfad in einer Ersetzung im Kontext pro Verzeichnis (htaccess) verwenden, es sei denn, eine der folgenden Bedingungen ist erfüllt:

  • Die ursprüngliche Anforderung und die Ersetzung befinden sich unter dem DocumentRoot (im Gegensatz zu anderen Mitteln wie Alias).

  • Der Dateisystempfad zu dem Verzeichnis, das die RewriteRule enthält, an die die relative Ersetzung angehängt ist, ist auch als URL-Pfad auf dem Server gültig (dies ist selten).

Wie bereits erwähnt, ist es in anderen Kontexten nur nützlich, Ihre Regel zu verkürzen. Darüber hinaus können Sie, wie bereits erwähnt, dasselbe erreichen, indem Sie die Datei htaccess im Unterverzeichnis ablegen.

Alex
quelle