Dies ist eine kanonische Frage zu Apaches mod_rewrite.
Das Ändern einer Anforderungs-URL oder das Umleiten von Benutzern zu einer anderen URL als der ursprünglich angeforderten erfolgt mit mod_rewrite. Dies beinhaltet solche Dinge wie:
- Ändern von HTTP zu HTTPS (oder umgekehrt)
- Ändern einer Anfrage auf eine Seite, die nicht mehr existiert, um eine neue zu ersetzen.
- Ändern eines URL-Formats (z. B.? Id = 3433 in / id / 3433)
- Präsentieren einer anderen Seite basierend auf dem Browser, basierend auf dem Referrer, basierend auf allem, was unter Mond und Sonne möglich ist.
- Alles, was Sie mit URL herumspielen möchten
Alles, was Sie schon immer über Mod_Rewrite-Regeln wissen wollten, aber keine Angst hatten zu fragen!
Wie kann ich Experte beim Schreiben von mod_rewrite-Regeln werden?
- Was ist das grundlegende Format und die Struktur von mod_rewrite-Regeln?
- Welche Form / Geschmack von regulären Ausdrücken muss ich beherrschen?
- Was sind die häufigsten Fehler / Fallstricke beim Schreiben von Umschreiberegeln?
- Was ist eine gute Methode zum Testen und Überprüfen von mod_rewrite-Regeln?
- Gibt es SEO- oder Performance-Auswirkungen von mod_rewrite-Regeln, auf die ich achten sollte?
- Gibt es Situationen, in denen mod_rewrite als das richtige Werkzeug für den Job erscheint, aber nicht?
- Was sind einige gängige Beispiele?
Ein Ort, um Ihre Regeln zu testen
Die htaccess-Tester -Website ist ein großartiger Ort, um mit Ihren Regeln herumzuspielen und sie zu testen. Es wird sogar die Debug-Ausgabe angezeigt, sodass Sie sehen können, was übereinstimmt und was nicht.
apache-2.2
mod-rewrite
redirect
redirection
301-redirect
Kyle Brandt
quelle
quelle
mod-rewrite
Randes von Tag-Suchen / Filtern angezeigt werden muss.Antworten:
Syntaxreihenfolge von mod_rewrite
mod_rewrite hat einige spezielle Ordnungsregeln, die sich auf die Verarbeitung auswirken. Bevor etwas getan wird, muss die
RewriteEngine On
Direktive angegeben werden, da dies die Verarbeitung von mod_rewrite einschaltet. Dies sollte vor allen anderen Umschreibeanweisungen erfolgen.RewriteCond
vorhergehendeRewriteRule
macht diese EINE Regel abhängig von der Bedingung. Alle folgenden RewriteRules werden so verarbeitet, als wären sie nicht an Bedingungen geknüpft.In diesem einfachen Fall, wenn der HTTP-Verweis von serverfault.com stammt, leiten Sie Blog-Anfragen auf spezielle Serverfehlerseiten um (wir sind nur das Besondere). Wenn der obige Block jedoch eine zusätzliche RewriteRule-Zeile hatte:
Alle .jpg-Dateien werden auf die speziellen Serverfehlerseiten verschoben, nicht nur auf diejenigen mit einem Verweis, der angibt, dass sie von hier stammen. Dies ist eindeutig nicht die Absicht der Art und Weise, wie diese Regeln geschrieben sind. Dies könnte mit mehreren RewriteCond-Regeln geschehen:
Aber wahrscheinlich sollte dies mit etwas kniffligerer Ersatzsyntax geschehen.
Die komplexere RewriteRule enthält die Bedingungen für die Verarbeitung. Die letzte Klammer
(html|jpg)
weist RewriteRule an, entweder nachhtml
oder zu suchenjpg
und die gefundene Zeichenfolge als $ 2 in der neu geschriebenen Zeichenfolge darzustellen. Dies ist logisch identisch mit dem vorherigen Block, mit zwei RewriteCond / RewriteRule-Paaren, es wird nur auf zwei Zeilen anstatt auf vier ausgeführt.Mehrere RewriteCond-Zeilen sind implizit UND-verknüpft und können explizit ODER-verknüpft werden. So behandeln Sie Verweise von ServerFault und Super User (explizites ODER):
So bedienen Sie ServerFault-bezogene Seiten mit Chrome-Browsern (implizites UND):
RewriteBase
ist auch auftragsspezifisch, da angegeben wird, wie die folgendenRewriteRule
Anweisungen ihre Verarbeitung handhaben. Es ist sehr nützlich in .htaccess-Dateien. Bei Verwendung sollte dies die erste Anweisung unter "RewriteEngine on" in einer .htaccess-Datei sein. Nehmen Sie dieses Beispiel:Dies sagt mod_rewrite, dass diese bestimmte URL, die derzeit verarbeitet wird, über http://example.com/blog/ anstelle des physischen Verzeichnispfads (/ home / $ Benutzername / public_html / blog) angekommen ist, und behandelt sie entsprechend. Aus diesem Grund wird davon
RewriteRule
ausgegangen, dass die Zeichenfolge nach dem "/ blog" in der URL beginnt. Hier ist das Gleiche auf zwei verschiedene Arten geschrieben. Eine mit RewriteBase, die andere ohne:Wie Sie sehen,
RewriteBase
können Sie durch das Umschreiben von Regeln den Pfad der Website zum Inhalt und nicht zum Webserver nutzen , wodurch diese für diejenigen verständlicher werden, die solche Dateien bearbeiten. Außerdem können sie die Richtlinien kürzer machen, was ästhetisch ansprechend ist.RewriteRule-Matching-Syntax
RewriteRule selbst verfügt über eine komplexe Syntax zum Abgleichen von Zeichenfolgen. Ich werde die Flaggen (Dinge wie [PT]) in einem anderen Abschnitt behandeln. Da Sysadmins häufiger anhand von Beispielen lernen als durch Lesen einer Manpage, werde ich Beispiele geben und erklären, was sie tun.
Das
.*
Konstrukt entspricht einem einzelnen Zeichen (.
) null oder mehrmals (*
). Durch das Einschließen in Klammern wird die Zeichenfolge angegeben, die als $ 1-Variable abgeglichen wurde.In diesem Fall war das erste. * NICHT in den Parens enthalten und wird daher nicht für die umgeschriebene Zeichenfolge bereitgestellt. Diese Regel entfernt eine Verzeichnisebene auf der neuen Blog-Site. (/blog/2009/sample.html wird zu /newblog/sample.html).
In diesem Fall richtet der erste Ausdruck in Klammern eine übereinstimmende Gruppe ein. Dies wird zu $ 1, was nicht benötigt und daher in der neu geschriebenen Zeichenfolge nicht verwendet wird.
In diesem Fall verwenden wir $ 1 in der umgeschriebenen Zeichenfolge.
Diese Regel verwendet eine spezielle Klammer - Syntax , die ein Zeichen gibt Bereich . [0-9] entspricht den Ziffern 0 bis 9. Diese spezielle Regel behandelt Jahre von 2000 bis 2099.
Dies macht das Gleiche wie die vorherige Regel, aber der Abschnitt {2} sagt, dass es zweimal mit dem vorherigen Zeichen (in diesem Fall mit einem Klammerausdruck) übereinstimmen soll.
Dieser Fall stimmt mit jedem Kleinbuchstaben im zweiten übereinstimmenden Ausdruck überein, und zwar für so viele Zeichen wie möglich. Das
\.
Konstrukt weist es an, die Periode als eine tatsächliche Periode zu behandeln, nicht das Sonderzeichen, das es in den vorherigen Beispielen ist. Es wird jedoch unterbrochen, wenn der Dateiname Striche enthält.Dies fängt Dateinamen mit Bindestrichen ein. Da
-
es sich jedoch um ein Sonderzeichen in Klammern handelt, muss es das erste Zeichen im Ausdruck sein.Diese Version fängt jeden Dateinamen mit Buchstaben, Zahlen oder dem
-
Zeichen im Dateinamen ein. Auf diese Weise geben Sie mehrere Zeichensätze in einem Klammerausdruck an.RewriteRule-Flags
Die Flags für Umschreiberegeln haben eine Vielzahl von speziellen Bedeutungen und Verwendungszwecken .
Das Flag steht
[L]
am Ende des obigen Ausdrucks. Es können mehrere durch Komma getrennte Flags verwendet werden. Die verlinkten Dokumentationen beschreiben jeden einzelnen, aber hier sind sie trotzdem:L = Letzte. Stoppen Sie die Verarbeitung von RewriteRules, sobald diese übereinstimmt. Bestellung zählt!
C = Kette. Fahren Sie mit der Verarbeitung der nächsten RewriteRule fort. Wenn diese Regel nicht übereinstimmt, wird die nächste Regel nicht ausgeführt. Dazu später mehr.
E = Umgebungsvariable einstellen. Apache verfügt über verschiedene Umgebungsvariablen, die sich auf das Verhalten von Webservern auswirken können.
F = Verboten. Gibt einen 403-Forbidden-Fehler zurück, wenn diese Regel zutrifft.
G = gegangen. Gibt einen 410-Gone-Fehler zurück, wenn diese Regel zutrifft.
H = Handler. Erzwingt, dass die Anforderung wie der angegebene MIME-Typ behandelt wird.
N = Weiter. Erzwingt, dass die Regel erneut gestartet und abgeglichen wird. ACHTUNG! Dies kann zu Schleifen führen.
NC = Kein Fall. Erlaubt
jpg
passend zu jpg und JPG.NE = kein Entrinnen. Verhindert das Umschreiben von Sonderzeichen (.? # & Etc) in ihre Hex-Code-Entsprechungen.
NS = Keine Unteranfragen. Wenn Sie serverseitige Includes verwenden, werden Übereinstimmungen mit den enthaltenen Dateien verhindert.
P = Proxy. Erzwingt die Behandlung der Regel durch mod_proxy. Stellen Sie Inhalte von anderen Servern transparent bereit, da Ihr Webserver sie abruft und erneut bereitstellt. Dies ist eine gefährliche Flagge, da eine schlecht geschriebene Ihren Webserver in einen offenen Proxy verwandelt und That is Bad.
PT = Pass Through. Berücksichtigen Sie Alias-Anweisungen beim RewriteRule-Abgleich.
QSA = QSAppend. Wenn die ursprüngliche Zeichenfolge eine Abfrage enthält ( http://example.com/thing?asp=foo) Hängen Sie die ursprüngliche Abfragezeichenfolge an die umgeschriebene Zeichenfolge an. Normalerweise wird es verworfen. Wichtig für dynamischen Inhalt.
R = Umleiten. Stellen Sie eine HTTP-Umleitung zur angegebenen URL bereit. Kann auch einen genauen Weiterleitungscode bereitstellen [R = 303]. Sehr ähnlich
RedirectMatch
, was schneller ist und wenn möglich verwendet werden sollte.S = Überspringen. Überspringe diese Regel.
T = Typ. Geben Sie den MIME-Typ des zurückgegebenen Inhalts an. Sehr ähnlich der
AddType
Richtlinie.Weißt du, wie ich sagte, dass dies
RewriteCond
nur für eine Regel gilt? Nun, das können Sie umgehen, indem Sie sie verketten.Da die erste RewriteRule das Chain-Flag hat, wird die zweite RewriteRule ausgeführt, wenn die erste dies tut. Dies ist der Fall, wenn die vorherige RewriteCond-Regel übereinstimmt. Praktisch, wenn Apache-reguläre Ausdrücke Ihr Gehirn verletzen. Die All-in-One-Line-Methode, auf die ich im ersten Abschnitt verweise, ist jedoch unter dem Gesichtspunkt der Optimierung schneller.
Dies kann durch Flags vereinfacht werden:
Einige Flags gelten auch für RewriteCond. Vor allem NoCase.
Entspricht "ServerFault.com"
quelle
mod_rewrite
und reguläre Grundierung. +1.RewriteCond
tatsächlich verarbeitet wird, nachdem dasRewriteRule
übereinstimmt. Möglicherweise möchten Sie "dazu später mehr" in der Nähe der Spitze sagen, wo Sie "RewriteCond vor RewriteRule macht diese EINE Regel abhängig von der Bedingung" sagen. Vielleicht möchten Sie erwähnen, dass die regulären Ausdrücke Perl-kompatibel sind. Außerdem haben Sie ein fremdes Apostroph in "... die RewriteRule betrachtet es als String-Start ..."RewriteRule ^/blog/.*/(.*)$ /newblog/$1
stimmt nicht mit der ersten Verzeichniskomponente überein - Umschreibungen sind standardmäßig gierig. /.*/(.*) stimmt sowohl mit / 1 / (2) / als auch mit / 1/2/3/4/5 / (6) / überein, sodass Sie / [^ /] * / nur für den ERSTEN Pfad benötigen Komponente.Ich werde mich auf die ausgezeichnete Antwort von sysadmin1138 zu diesen Punkten beschränken.
Zusätzlich zu der von sysadmin1138 beschriebenen Syntaxreihenfolge, Syntaxanpassung / regulären Ausdrücken und RewriteRule-Flags sollte erwähnt werden, dass mod_rewrite Apache-Umgebungsvariablen basierend auf HTTP-Anforderungsheadern und der Apache-Konfiguration verfügbar macht.
Ich würde AskApaches mod_rewrite-Debug-Tutorial für eine umfassende Liste von Variablen empfehlen, die mod_rewrite zur Verfügung stehen könnten.
Die meisten Probleme mit RewriteRule resultieren aus einem Missverständnis der PCRE-Syntax / dem Versagen, Sonderzeichen richtig zu entkommen, oder einem Mangel an Einsicht in den Inhalt der Variablen, die für den Abgleich verwendet werden.
Typische Probleme und empfohlene Fehlerbehebung:
IfModule
um dieses Szenario zu vermeiden, müssen Sie Anweisungen umbrechen)Schauen Sie sich zunächst den Inhalt der Umgebungsvariablen an, mit denen Sie übereinstimmen möchten. Wenn Sie PHP installiert haben, müssen Sie lediglich den folgenden Block zu Ihrer Anwendung hinzufügen:
... schreiben Sie dann Ihre Regeln (vorzugsweise zum Testen auf einem Entwicklungsserver) und notieren Sie sich inkonsistente Übereinstimmungen oder Aktivitäten in Ihrer Apache ErrorLog- Datei.
Verwenden Sie für komplexere Regeln die
RewriteLog
Anweisung von mod_rewrite , um Aktivitäten in einer Datei zu protokollieren und festzulegenRewriteLogLevel 3
AllowOverride all
Beeinträchtigt die Serverleistung, da Apache.htaccess
bei jeder Anforderung nach Dateien suchen und Anweisungen analysieren muss. Behalten Sie nach Möglichkeit alle Anweisungen in der VirtualHost-Konfiguration für Ihre Site bei oder aktivieren Sie.htaccess
Überschreibungen nur für die Verzeichnisse, die sie benötigen.In den Webmaster-Richtlinien von Google heißt es ausdrücklich: "Täuschen Sie Ihre Nutzer nicht und präsentieren Sie Suchmaschinen keine anderen Inhalte als die, die Sie den Nutzern anzeigen. Dies wird im Allgemeinen als" Cloaking "bezeichnet." - Vermeiden Sie es, mod_rewrite-Direktiven zu erstellen, die nach Suchmaschinenrobotern filtern.
Suchmaschinenroboter bevorzugen eine 1: 1-Zuordnung von Inhalten zu URIs (dies ist die Grundlage für die Rangfolge von Links zu Inhalten). Wenn Sie mit mod_rewrite temporäre Weiterleitungen erstellen oder denselben Inhalt unter mehreren URIs bereitstellen, sollten Sie in Erwägung ziehen, einen kanonischen URI in anzugeben Ihre HTML-Dokumente.
Dies ist ein großes (und potenziell umstrittenes) Thema für sich - besser (IMHO), um die Verwendungszwecke von Fall zu Fall zu regeln und den Fragestellern zu ermöglichen, festzustellen, ob die vorgeschlagenen Lösungen ihren Bedürfnissen entsprechen.
Die mod_rewrite-Tricks und -Tipps von AskApache decken nahezu jeden gängigen Anwendungsfall ab, der regelmäßig angezeigt wird. Die "richtige" Lösung für einen bestimmten Benutzer hängt jedoch möglicherweise von der Komplexität der Benutzerkonfiguration und den vorhandenen Anweisungen ab eine gute Idee, um zu sehen, welche anderen Anweisungen ein Benutzer hat, wenn eine mod_rewrite-Frage auftaucht).
quelle
Redirect
oderRedirectMatch
. Siehe auch die Apache-Dokumentation: Wann man mod_rewrite nicht benutztWie viele Administratoren / Entwickler kämpfe ich seit Jahren gegen die Kompliziertheit des Umschreibens von Regeln und bin mit der vorhandenen Apache-Dokumentation unzufrieden. Deshalb habe ich mich als persönliches Projekt entschieden, um herauszufinden, wie
mod_rewrite
der Rest des Apache tatsächlich funktioniert und mit ihm interagiert Kern, also habe ich in den letzten Monaten Testfälle mitstrace
+ Drill-In im Quellcode instrumentiert , um all dies in den Griff zu bekommen.Hier sind einige wichtige Kommentare, die Entwickler von Umschreiberegeln berücksichtigen müssen:
.htaccess
Verarbeitung zum Teil erheblich von der bei PerDir ( ).Ich würde sagen, dass Sie aus diesem Grund die Benutzergemeinschaften für das Neuschreiben fast in zwei Kategorien aufteilen und sie als vollständig getrennt behandeln müssen:
Diejenigen mit Root-Zugriff auf die Apache-Konfiguration . Dies sind in der Regel Administratoren / Entwickler mit einem anwendungsspezifischen Server / einer anwendungsspezifischen VM. Die folgende Meldung ist recht einfach: Vermeiden Sie die Verwendung von
.htaccess
Dateien, wenn dies möglich ist. mach alles in deiner server oder vhost config. Das Debuggen ist relativ einfach, da der Entwickler das Debuggen festlegen kann und Zugriff auf die rewrite.log-Dateien hat.Benutzer eines gemeinsam genutzten gehosteten Dienstes (Shared Hosted Service, SHS) .
.htaccess
/ Perdir Verarbeitung , da es keine Alternative zur Verfügung steht..htaccess
Datei ausgewählt wurde und warum. Es erklärt nicht die Feinheiten des PerDir-Radfahrens und wie dies vermieden werden kann.Möglicherweise gibt es eine dritte Community: Administrations- und Support-Mitarbeiter von SHS-Anbietern, die in beiden Lagern einen Fuß haben und unter den oben genannten Konsequenzen leiden müssen.
Ich habe ein paar Artikel-artige Blog-Posts geschrieben (z. B. Mehr zur Verwendung von Rewrite-Regeln in .htaccess-Dateien ), die viele detaillierte Punkte behandeln, die ich hier nicht wiederholen werde, um diesen Beitrag kurz zu halten. Ich habe meinen eigenen gemeinsamen Service und unterstütze einige dedizierte & VM FLOSS-Projekte. Ich habe zunächst eine Standard-LAMP-VM als Testfahrzeug für mein SHS-Konto verwendet, fand es aber am Ende besser, eine richtige Spiegel-VM ( hier beschrieben ) zu erstellen .
In Bezug auf die Art und Weise, wie die Admin-Community
.htaccess
Benutzer unterstützen soll , sind wir jedoch der Ansicht, dass wir Folgendes entwickeln und anbieten müssen:.htaccess
UmschreiberegelnTipps, wie Sie aus Ihren Regeln eine integrierte Diagnose erhalten (z. B.
[E=VAR:EXPR]
die Tatsache, dassEXPR
Rückverweise ($ N oder% N) erweitert werden, um sie als Diagnose für das Zielskript verfügbar zu machen.Wenn Sie Ihre Umschreiberegeln mit den Flags [OR], [C], [SKIP] und [L] aktuell anordnen, sodass das gesamte Umschreibeschema funktioniert, ohne dass die interne Umleitung ausgenutzt werden muss, können Sie Folgendes als Regel 1 hinzufügen, um dies zu vermeiden Alle Probleme mit dem Looping:
quelle
.htaccess
Themen zu abonnieren, und Sie werden sehen. Die meisten Anfänger sind hoffnungslos verwirrt - die meisten haben ihre ersten Erfahrungen mit einem LAMP-Dienst und mod_rewrite auf einem gemeinsam genutzten Dienst und haben daher keinen Root-Zugriff auf die System- / vhost-Konfigurationen und müssen die Verarbeitung pro Verzeichnis über.htaccess
Dateien durchführen. Es gibt wichtige Unterschiede, über die der Anfänger "bluten" muss. Ich würde mich als Power-User sehen und entdecke immer noch Feinheiten. Wie ich schon sagte, musste ich Strace- und Source-Code-Scannen verwenden, um einige Aspekte herauszufinden. Sollte nicht benötigt werden. :-(.htaccess
, was selbst für Experten furchtbar zerbrechlich, kompliziert und verwirrend ist. Ich habe immer noch Probleme.Verwenden der Umschreibekarte
Es gibt viele Dinge, die Sie mit Umschreibekarten tun können. Rewritemaps werden mit der Rewritemap-Direktive deklariert und können dann sowohl in RewritCond-Auswertungen als auch in RewriteRule Subsitutions verwendet werden.
Die allgemeine Syntax für RewriteMap lautet:
Zum Beispiel:
Sie können dann den Mapnamen für Konstrukte wie das folgende verwenden:
Die Map enthält Schlüssel / Wert-Paare. Wird der Schlüssel gefunden, wird der Wert ersetzt. Einfache Maps sind nur reine Textdateien, aber Sie können Hash-Maps und sogar SQL-Abfragen verwenden. Weitere Details finden Sie in den Dokumenten:
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap
Entspannende Saiten.
Es gibt vier interne Maps, mit denen Sie einige Änderungen vornehmen können. Besonders unausweichliche Saiten können sich als nützlich erweisen.
Zum Beispiel: Ich möchte in der Abfragezeichenfolge auf die Zeichenfolge "café" testen. Der Browser wird dies jedoch umgehen, bevor er es an meinen Server sendet. Daher muss ich entweder für jede Zeichenfolge, die ich abgleichen möchte, herausfinden, welche URL-Escape-Version verwendet wird, oder ich kann sie einfach wieder entfernen ...
Beachten Sie, wie ich eine RewriteCond verwende, um nur das Argument des Abfragezeichenfolgenparameters zu erfassen, und dann die Map in der zweiten RewriteCond zu verwenden, um sie zu entschlüsseln. Dies wird dann verglichen. Beachten Sie auch, wie ich% 2 als Schlüssel in der Umschreibekarte verwenden muss, da% 1 entweder "Ort" oder "Ort" enthält. Wenn Sie Klammern verwenden, um Muster zu gruppieren, werden diese ebenfalls erfasst, ob Sie das Ergebnis der Erfassung verwenden möchten oder nicht ...
quelle
mod_rewrite
Regexp-Engine unterstützt Gruppen, die keine Erfassung vornehmen, wie z. B.(?:location|place)
und für diese wird im Beispiel nur eine Erfassung durchgeführt.Eine sehr einfache Falle ist das Umschreiben von URLs, die den scheinbaren Pfad ändern, z . B. von
/base/1234/index.html
nach/base/script.php?id=1234
. Bilder oder CSS mit relativen Pfaden zum Skriptspeicherort werden vom Client nicht gefunden. Eine Reihe von Optionen zur Lösung dieses Problems finden Sie in dieser FAQ .quelle
<base>
am einfachsten, ein Tag hinzuzufügen und dennoch relative Pfade zu aktivieren.