Ich möchte eine mod_rewrite RewriteRule erstellen, die unabhängig von dem Speicherort der Webseite ist. Ich möchte die Umschreiberegel in einer .htaccess-Datei definieren. Nehmen wir dies als Beispiel:
RewriteEngine on
RewriteRule ^(.*)\.html html.php
Mit dieser Regel möchte ich alle * .html-Anforderungen einem html.php-Skript zuordnen, das sich im Webstamm befindet. Das Problem ist, dass sich die öffentliche Basis-URL der Webroot ändern kann. Das Webstammverzeichnis könnte sich also in http://www.somewhere.tld/
oder in einem Unterverzeichnis unter befinden http://www.somewhere.tld/foo/bar/
.
Die Verwendung eines relativen Pfads in einer Umschreiberegel funktioniert jedoch nicht. Also muss ich eines davon schreiben:
/html.php (When web is located in root directory of the web)
/foo/bar/html.php (When web is located in foo/bar sub directory)
Alternativ kann ich eine RewriteBase festlegen, aber ich möchte diesen Pfad einfach überhaupt nicht konfigurieren. Ich möchte, dass Apache automatisch das Richtige tut, damit ich das Web einfach in ein Verzeichnis kopieren kann und es funktioniert, ohne die Umschreiberegeln mitzuteilen, in denen sich das Web befindet. Wie kann ich das tun?
quelle
.htaccess
, Sie haben Bereitstellung einer nicht bereits festgelegt) anRewriteBase
anderer Stelle in der Config (einschließlich aller geerbten configs, wenn mod_rewrite Erbe gewesen installieren). Beachten Sie, dass dies interne Umschreibungen betrifft (wie in der Frage und allen Antworten unten verwendet), nicht externe Weiterleitungen (die in der Tat ein Problem darstellen würden).Antworten:
Meines Wissens nach gibt es keine Möglichkeit, dies zu erreichen. Sie müssen RewriteBase konfigurieren. Eine Möglichkeit besteht darin, die Einrichtung von RewriteBase mithilfe eines PHP-Skripts zu automatisieren. Dafür ist jedoch (zumindest) eine Schreibberechtigung für den .htaccess erforderlich. Sie müssen die RewriteBase jedoch in .htaccess konfigurieren.
quelle
Ich habe mit dem gleichen Problem und aus dem gleichen Grund gekämpft. Ich versuche, eine Web-App unabhängig von dem Ort zu machen, an dem sie installiert ist, ohne auf ein Konfigurationsskript oder einen manuellen Benutzereingriff zurückzugreifen. Lass die App einfach irgendwo fallen und lass sie ihre Sache machen.
Und es scheint doch eine Lösung zu geben, zumindest für Apache 2. Nimmt vier Zeilen. Das Denken dahinter zu erklären dauert allerdings mehr als vier Zeilen;)
Versuchen Sie Folgendes:
Hier ist das Wie und Warum
Wir können die RewriteBase nicht dynamisch festlegen, daher setzen wir sie ein für alle Mal auf die Stamm-URL des Servers :
RewriteBase /
. Dies sorgt für Konsistenz, bedeutet aber auch, dass wir den URL-Pfad zum aktuellen Verzeichnis selbst festlegen und ihn der neu geschriebenen URL voranstellen müssen.In welchem Verzeichnis befinden wir uns? Nehmen wir ein
REQUEST_URI
von / some / path / app-root / virtual / stuff an. Unser htaccess ist in App-Root. Wenn wir den virtuellen Teil - virtual / stuff - greifen und ihn aus dem entfernenREQUEST_URI
, bleibt uns der URL-Pfad zu unserem App-Verzeichnis.Das Erfassen des virtuellen Teils ist unkompliziert und kann in der Umschreiberegel selbst erfolgen.
RewriteRule ^(.*)$ ...
macht es in der$1
Variablen verfügbar .Jetzt führen wir unsere kleine Zeichenfolgenoperation aus und entfernen den virtuellen Teil aus dem Anforderungs-URI. Wir haben keine String-Befehle dafür, aber RewriteCond kann mit Strings übereinstimmen und Teilzeichenfolgen erfassen. Daher fügen wir eine RewriteCond hinzu, um den URL-Pfad zum aktuellen Verzeichnis zu extrahieren. Ansonsten sollte der "Zustand" uns aus dem Weg gehen und immer wahr sein.
Wir können die
$1
Variable aus der RewriteRule in der RewriteCond verwenden, da mod_rewrite einen Regelsatz tatsächlich rückwärts verarbeitet. Es beginnt mit dem Muster in der Regel selbst und überprüft, wenn es übereinstimmt, die Bedingungen. Die Variable ist also bis dahin verfügbar.Während die Testzeichenfolge in der RewriteCond die Variable verwenden kann, kann der Regex der tatsächlichen Bedingung dies nicht. Innerhalb der Bedingung können wir nur interne Rückverweise verwenden. Also setzen wir zuerst eine Testzeichenfolge "[virtueller Teil] [ein Trennzeichen] [Anfrage uri]" zusammen. Das Zeichen '#' ist ein gutes Trennzeichen, da es nicht in der URL angezeigt wird. Als nächstes vergleichen wir es mit einer Bedingung von
Hier ist also die vollständige Bedingung :
RewriteCond $1#%{REQUEST_URI} ([^#]*)#(.*?)\1$
.Die zweite erfasste Gruppe in der RewriteCond-Regex ist unser Standort. Wir müssen es nur der neu geschriebenen URL mit einem
%2
Verweis voranstellen . Das lässt uns mitRewriteRule ^(.*)$ %2index.php [QSA,L]
. Voilà.Ich habe noch keine umfangreichen Tests durchgeführt, aber ich habe festgestellt, dass es sowohl mit normalen virtuellen Hosts als auch mit virtuellem Massenhosting (unter Verwendung von VirtualDocumentRoot) funktioniert. Implizit sollten auch andere Alias-Speicherorte in Ordnung sein.
Apache 1.3
Apache 1.3 gibt es leider immer noch und es wird das RewriteCond-Muster ersticken. Apache 1.3 unterstützt den Modifikator "unreedy" (das "?" In
(.*?)
) nicht.Aber für Apache 2 sollte es den Trick machen. Ich würde mich auf jeden Fall über Feedback freuen, insbesondere wenn es in Ihrer Umgebung fehlschlägt.
Bearbeiten: Ich habe gerade einen umfassenderen Artikel zu diesem Thema in meinem Blog veröffentlicht (" Verwenden von mod_rewrite in .htaccess-Dateien ohne Kenntnis der RewriteBase "). Weitere Details finden Sie dort.
quelle
/some/path/app-root/virtual//stuff
(beachten Sie die doppelten Schrägstriche) ist, da Apache diese Schrägstriche entfernt, wenn sie mit dem URL-Pfad in derRewriteRule
Direktive^(.*)$
virtual//stuff
RewriteBase /
. Dies sorgt für Konsistenz" - dies scheint der Fehler zu sein . Warum müssen Sie dasRewriteBase
in diesem Zusammenhang überhaupt einstellen ? Warum für "Konsistenz"?RewriteBase
hat einen bestimmten Zweck; das ist es nicht. Wenn Sie a nicht festlegenRewriteBase
, können Sie einfach eine relative Pfadsubstitution verwenden - Problem gelöst. Siehe meine Antwort .Ich finde die Dokumentation von Apache irreführend:
Das zurückgesetzte Präfix ist jedoch völlig anders (Pfad auf der Festplatte anstelle der ursprünglichen URL). Ich kann mir keine Situation vorstellen, in der dies das richtige Verhalten wäre.
quelle
RewriteBase
oder" root-relativ (oder absolut - was einige sagen, dass Sie immer verwenden sollten) überschreiben. URLs.Wie wäre es mit so etwas
In meinem Beispiel wird jedoch der Dateinamensbereich der HTML-Datei beibehalten. Beispielsweise wird page1.html in page1 / html.php umgeleitet. (Hinweis: Ich habe dies überhaupt nicht getestet, versuche es auf eigenes Risiko :))
Außerdem enthält die mod_rewrite-Anleitung unzählige Beispiele, die Ihrem Problem ähneln. Hast du dir das schon angesehen?
quelle
In der Frage ist nicht klar, was in diesem Zusammenhang tatsächlich den Standort des "Webstamms" bestimmt. (Da es sich deutlich vom Dokumentenstamm unterscheidet .)
Zur Beantwortung gehe ich davon aus, dass das "Webstammverzeichnis" das Verzeichnis ist, in dem die Webanwendung installiert ist. Dies sollte auch der Speicherort der
.htaccess
Datei sein, die diese "Webanwendung" steuert (nicht im Dokumentstamm).In diesem Fall Sie können nur eine relative Pfad Substitution verwenden. Sie müssen nicht eine Verwendung
RewriteBase
Richtlinie (die den Verzeichnis-Präfix überschreibt , die später wieder hinzugefügt wird und nicht „dynamisch“ gesetzt werden).Wenn also das "Webstamm" ist, sollte
/foo/bar
das.htaccess
at/foo/bar/.htaccess
ungefähr so lauten:(Das
RewriteRule
Muster Suffix^(.*)
ist hier überflüssig.)Bei einer entsprechenden Anfrage
/foo/bar/baz/something.html
wird die Anfrage intern in<document-root>/foo/bar/html.php
(Dateisystempfad) umgeschrieben .<document-root>/foo/bar/
ist das "Verzeichnispräfix" (der Dateisystempfad des Speicherorts der.htaccess
Datei), das allen relativen Pfadsubstitutionen wieder hinzugefügt wird.Standardmuster des Frontcontrollers (
.htaccess
Datei befindet sich unter<web-application-root>/.htaccess
):Legen Sie die
RewriteBase
Richtlinie nicht fest.Beachten Sie, dass sich die Frage und alle Beispiele auf dieser Seite auf interne Umschreibungen und nicht auf externe Weiterleitungen beziehen . Nur wenn es sich um externe Weiterleitungen handelt , müssen wir die effektive Basis-URL (oder
RewriteBase
) (dynamisch) festlegen / berechnen . Wenn Sie zulassen, dass das Verzeichnispräfix im Falle einer externen Umleitung wieder zu einer relativen Ersetzung hinzugefügt wird, tritt höchstwahrscheinlich eine ungültige Umleitung auf.quelle