In mod_rewrite
letzter Zeit scheint es eine anständige Anzahl von Threads zu geben, die ein wenig verwirrt darüber sind, wie bestimmte Aspekte davon funktionieren. Aus diesem Grund habe ich einige Hinweise zur allgemeinen Funktionalität und möglicherweise einige nervige Nuancen zusammengestellt.
Welche anderen Funktionen / häufigen Probleme sind Ihnen begegnet mod_rewrite
?
apache
.htaccess
mod-rewrite
Owen
quelle
quelle
Antworten:
Wo können mod_rewrite-Regeln platziert werden?
mod_rewrite
Regeln können in derhttpd.conf
Datei oder in der.htaccess
Datei platziert werden. Wenn Sie Zugriff auf haben,httpd.conf
bietet das Platzieren von Regeln hier einen Leistungsvorteil (da die Regeln einmal verarbeitet werden, im Gegensatz zu jedem.htaccess
Aufruf der Datei).Protokollierung von mod_rewrite-Anforderungen
Die Protokollierung kann innerhalb der
httpd.conf
Datei (einschließlich<Virtual Host>
) aktiviert werden :Häufige Anwendungsfälle
So leiten Sie alle Anfragen an einen einzigen Punkt weiter:
Seit Apache 2.2.16 können Sie auch verwenden
FallbackResource
.Umgang mit 301/302 Weiterleitungen:
Hinweis : Externe Weiterleitungen sind implizit 302 Weiterleitungen:
SSL erzwingen
Gemeinsame Flaggen:
[R]
oder[redirect]
- eine Umleitung erzwingen (standardmäßig eine temporäre Umleitung 302)[R=301]
oder[redirect=301]
- eine permanente 301-Umleitung erzwingen[L]
oder[last]
- Beenden Sie den Umschreibvorgang (siehe Hinweis unten in den häufigsten Fallstricken).[NC]
oder[nocase]
- Geben Sie an, dass beim Abgleichen die Groß- und Kleinschreibung nicht berücksichtigt werden sollDie Verwendung der Langform von Flags ist häufig besser lesbar und hilft anderen, die Ihren Code später lesen.
Sie können mehrere Flags durch ein Komma trennen:
Häufige Fehler
Mixing
mod_alias
Style Redirects mitmod_rewrite
Hinweis : Sie können mischen
mod_alias
mitmod_rewrite
, aber es ist mehr Arbeit als nur grundlegende Umleitungen wie oben Handhabung.Der Kontext beeinflusst die Syntax
In
.htaccess
Dateien wird im RewriteRule-Muster kein führender Schrägstrich verwendet:[L] ist nicht zuletzt! (manchmal)
Das
[L]
Flag beendet die Verarbeitung weiterer Umschreiberegeln für diesen Durchlauf durch den Regelsatz . Wenn die URL in diesem Durchgang geändert wurde und Sie sich im.htaccess
Kontext oder im<Directory>
Abschnitt befinden, wird Ihre geänderte Anforderung erneut über die URL-Analyse-Engine zurückgegeben. Und beim nächsten Durchgang kann es diesmal zu einer anderen Regel kommen. Wenn Sie dies nicht verstehen, sieht es oft so aus, als hätte Ihre[L]
Flagge keine Wirkung.Unser Umschreibungsprotokoll zeigt, dass die Regeln zweimal ausgeführt und die URL zweimal aktualisiert werden:
Der beste Weg, dies zu umgehen, besteht darin, das
[END]
Flag ( siehe Apache-Dokumente ) anstelle des[L]
Flags zu verwenden, wenn Sie wirklich die weitere Verarbeitung von Regeln (und nachfolgenden Durchläufen) stoppen möchten. Das[END]
Flag ist jedoch nur für Apache v2.3.9 + verfügbar. Wenn Sie also Version 2.2 oder niedriger haben, bleibt nur das[L]
Flag hängen .Bei früheren Versionen müssen Sie sich auf
RewriteCond
Anweisungen verlassen, um zu verhindern, dass Regeln bei nachfolgenden Durchläufen der URL-Analyse-Engine übereinstimmen.Oder Sie müssen sicherstellen, dass sich Ihre RewriteRule in einem Kontext befinden (dh
httpd.conf
), der nicht dazu führt, dass Ihre Anforderung erneut analysiert wird.quelle
[L]
Flag bedeutet, dass eine Regel in der aktuellen Verarbeitung die letzte ist. Dadurch wird das Umschreiben nicht beendet, da es sich um interne Weiterleitungen handelt. SiedirB
wenden sich alsodirC
bei der nächsten htaccess-Verarbeitung an. AlleineRewriteRule ^(.*)$ index.php?query=$1
wird eine Endlosschleife interner Weiterleitungen sein (in der Praxis wird sie nach 10 Iterationen beendet). -1, weil Sie vorschlagen, dass [L] nicht das letzte ist . Der Umschreibvorgang wird nicht beendet, aber er ist der letzte .RewriteCond %{HTTPS} off
ist die bevorzugte Methode, um nach einer HTTPS-Verbindung zu suchen (in Ihrem Beispiel, um Nicht-SSL-Verkehr zu HTTPS zuWenn Sie interne Weiterleitungen / Umschreibungen im .htaccess blockieren müssen, schauen Sie sich die an
Zustand, wie hier diskutiert .
quelle
.*
mit der[L]
Flagge vorschlagen, die ich gelesen habe, bevor ich hier ankam.200
,!=200
,^.
,^$
. Anscheinend wird die Variable200
für eine Umleitung auf gesetzt, aber auch auf anderen Seiten (Fehler und so) wird sie auf einen bestimmten Wert gesetzt. Nun das bedeutet , dass Sie entweder überprüfen , ob esis empty
,is not empty
,is 200
oderis not 200
, je nachdem , was Sie brauchen.Der Deal mit RewriteBase:
Sie müssen fast immer RewriteBase einstellen. Wenn Sie dies nicht tun, vermutet Apache, dass Ihre Basis der Pfad der physischen Festplatte zu Ihrem Verzeichnis ist. Beginnen Sie also damit:
quelle
RewriteBase .
oder etwas, das darauf hinweist, dass die URL gleich bleiben soll, nur was Sie angegeben haben?RewriteBase
ob Sie in derRewriteRule
Direktive die relative Pfadsubstitution verwenden. Es ist besser, relative Pfade zu vermeiden.RewriteBase
Entwicklerteam vermeiden wir dies insgesamt, da fast alle Entwickler falsch verstehen, was es tut. Wie @ w3d sagte, benötigen Sie es nur, wenn Sie Zeichen speichern und dieselbe Basis auf alle Ihre RewriteRules in einer Datei anwenden möchten. Ihr Code wird für andere wahrscheinlich klarer, wenn Sie ihn vermeiden.Andere Fallstricke:
1- Manchmal ist es eine gute Idee, MultiViews zu deaktivieren
Ich bin nicht mit allen MultiViews-Funktionen vertraut, aber ich weiß, dass es meine mod_rewrite-Regeln durcheinander bringt, wenn es aktiv ist, weil eine seiner Eigenschaften darin besteht, zu versuchen, eine Erweiterung einer Datei zu erraten, nach der ich zu suchen glaube .
Ich erkläre: Angenommen, Sie haben 2 PHP-Dateien in Ihrem Webverzeichnis, file1.php und file2.php, und Sie fügen diese Bedingungen und Regeln zu Ihrem .htaccess hinzu:
Sie gehen davon aus, dass alle URLs, die nicht mit einer Datei oder einem Verzeichnis übereinstimmen, von file1.php erfasst werden. Überraschung! Diese Regel wird für die URL http: // myhost / file2 / somepath nicht berücksichtigt . Stattdessen werden Sie in file2.php aufgenommen.
Was los ist, ist, dass MultiViews automatisch erraten hat, dass die URL, die Sie tatsächlich wollten, http: //myhost/file2.php/somepath war und Sie gerne dorthin gebracht hat.
Jetzt haben Sie keine Ahnung, was gerade passiert ist, und stellen an diesem Punkt alles in Frage, was Sie über mod_rewrite zu wissen glaubten. Sie fangen dann an, mit Regeln herumzuspielen, um zu versuchen, die Logik hinter dieser neuen Situation zu verstehen, aber je mehr Sie testen, desto weniger Sinn macht es.
Ok, kurz gesagt, wenn Sie möchten, dass mod_rewrite logisch funktioniert, ist das Deaktivieren von MultiViews ein Schritt in die richtige Richtung.
2- Aktivieren Sie FollowSymlinks
Das hier, ich kenne die Details nicht wirklich, aber ich habe es schon oft erwähnt gesehen, also mach es einfach.
quelle
+FollowSymLinks
wird in der Dokumentationmod_rewrite
aus vagen Sicherheitsgründen als obligatorisch für die Arbeit erwähnt.Die Gleichung kann mit folgendem Beispiel durchgeführt werden:
Dynamischer Lastausgleich:
Wenn Sie den mod_proxy verwenden, um Ihr System auszugleichen, können Sie einen dynamischen Bereich des Worker-Servers hinzufügen.
quelle
Ein besseres Verständnis des [L] -Flag ist angebracht. Das [L] -Flag ist das letzte. Sie müssen nur verstehen, was dazu führt, dass Ihre Anfrage erneut durch die URL-Analyse-Engine geleitet wird. Aus den Dokumenten ( http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l ) (Hervorhebung von mir):
Das Flag [L] beendet also die Verarbeitung weiterer Umschreiberegeln für diesen Durchlauf durch den Regelsatz. Wenn Ihre mit [L] gekennzeichnete Regel die Anforderung geändert hat und Sie sich im .htaccess-Kontext oder im
<Directory>
Abschnitt befinden, wird Ihre geänderte Anforderung erneut über die URL-Analyse-Engine zurückgegeben. Und beim nächsten Durchgang kann es diesmal zu einer anderen Regel kommen. Wenn Sie nicht verstehen, was passiert ist, hat Ihre erste Umschreiberegel mit dem Flag [L] anscheinend keine Auswirkung.Der beste Weg, dies zu umgehen, besteht darin, das Flag [END] ( http://httpd.apache.org/docs/current/rewrite/flags.html#flag_end ) anstelle des Flags [L] zu verwenden, wenn Sie wirklich aufhören möchten alle weitere Verarbeitung von Regeln (und anschließende Wiederholung). Das Flag [END] ist jedoch nur für Apache v2.3.9 + verfügbar. Wenn Sie also Version 2.2 oder niedriger haben, bleibt nur das Flag [L] hängen. In diesem Fall müssen Sie sich auf RewriteCond-Anweisungen verlassen, um zu verhindern, dass Regeln bei nachfolgenden Durchläufen der URL-Parsing-Engine übereinstimmen. Oder Sie müssen sicherstellen, dass sich Ihre RewriteRule in einem Kontext befinden (z. B. httpd.conf), der nicht dazu führt, dass Ihre Anforderung erneut analysiert wird.
quelle
Ein weiteres großartiges Feature sind Rewrite-Map-Erweiterungen. Sie sind besonders nützlich, wenn Sie eine große Anzahl von Hosts / Umschreibungen zu handhaben haben:
Sie sind wie ein Schlüssel-Wert-Ersatz:
Dann können Sie eine Zuordnung in Ihren Regeln verwenden, wie:
Weitere Informationen zu diesem Thema finden Sie hier:
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#mapfunc
quelle
.htaccess
-basierte Umschreibungen verwenden. In diesem Zusammenhang funktioniert es nicht.mod_rewrite kann Aspekte der Anforderungsbearbeitung ändern, ohne die URL zu ändern, z. B. das Setzen von Umgebungsvariablen, das Setzen von Cookies usw. Dies ist unglaublich nützlich.
Bedingt eine Umgebungsvariable festlegen:
Rückgabe einer 503-Antwort:
RewriteRule
Das[R]
Flag kann einen Nicht-3xx-Wert annehmen und eine nicht umleitende Antwort zurückgeben, z. B. für verwaltete Ausfallzeiten / Wartungsarbeiten:gibt eine 503-Antwort zurück (keine Umleitung an sich).
Außerdem kann mod_rewrite wie eine leistungsstarke Schnittstelle zu mod_proxy fungieren. Sie können dies also tun, anstatt
ProxyPass
Anweisungen zu schreiben :Meinung: Die Verwendung von
RewriteRule
s undRewriteCond
s zum Weiterleiten von Anforderungen an verschiedene Anwendungen oder Load Balancer basierend auf praktisch jedem denkbaren Aspekt der Anforderung ist einfach immens leistungsfähig. Durch die Steuerung von Anforderungen auf dem Weg zum Backend und die Möglichkeit, die Antworten auf dem Weg zurück zu ändern, ist mod_rewrite der ideale Ort, um alle routingbezogenen Konfigurationen zu zentralisieren.Nehmen Sie sich Zeit, um es zu lernen, es lohnt sich! :) :)
quelle