Leiten Sie um, ändern Sie URLs oder leiten Sie HTTP zu HTTPS in Apache um - alles, was Sie schon immer über Mod_Rewrite-Regeln wissen wollten, aber keine Angst hatten zu fragen

264

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.

Kyle Brandt
quelle
9
Die Idee hinter dieser Frage ist es, einen engen Weg für all die endlosen mod_rewrite-Fragen aufzuzeigen, die unsere regelmäßigeren Benutzer verrückt machen. Dies ist sehr ähnlich zu dem, was mit Subnetting unter serverfault.com/questions/49765/how-does-subnetting-work gemacht wurde .
Kyle Brandt
1
Außerdem möchte ich nicht zu viele Gegenstimmen zu dieser Frage , sondern sie sollten zur Antwort gehen. Ich möchte das nicht ändern, weil ich sicherstellen möchte, dass das Poster die volle Anerkennung dafür erhält, was ich hoffe, ist die Antwort von mod_rewrite, um alle Fragen von mod_rewrite zu beenden .
Kyle Brandt
4
Entschuldigung, ich habe die Frage positiv bewertet. ;-) Ich denke wirklich, dass es am (oder in der Nähe des) oberen mod-rewriteRandes von Tag-Suchen / Filtern angezeigt werden muss.
Steven Montag
Jemand anderes sollte die üblichen Anwendungsfälle behandeln. Ich kenne sie nicht gut genug, um es gerecht zu machen.
sysadmin1138
Vielleicht sollte diese Frage mit dem Mod-Rewrite-Tag-Wiki verknüpft werden, um den Pfad noch kürzer zu machen.
beldaz

Antworten:

224

Syntaxreihenfolge von mod_rewrite

mod_rewrite hat einige spezielle Ordnungsregeln, die sich auf die Verarbeitung auswirken. Bevor etwas getan wird, muss die RewriteEngine OnDirektive angegeben werden, da dies die Verarbeitung von mod_rewrite einschaltet. Dies sollte vor allen anderen Umschreibeanweisungen erfolgen.

RewriteCondvorhergehende RewriteRulemacht diese EINE Regel abhängig von der Bedingung. Alle folgenden RewriteRules werden so verarbeitet, als wären sie nicht an Bedingungen geknüpft.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html

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:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg         $/blog/$1.sf.jpg

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:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

Aber wahrscheinlich sollte dies mit etwas kniffligerer Ersatzsyntax geschehen.

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Die komplexere RewriteRule enthält die Bedingungen für die Verarbeitung. Die letzte Klammer (html|jpg)weist RewriteRule an, entweder nach htmloder zu suchen jpgund 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):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)    [OR]
RewriteCond %{HTTP_REFERER}                ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

So bedienen Sie ServerFault-bezogene Seiten mit Chrome-Browsern (implizites UND):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT}             ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

RewriteBaseist auch auftragsspezifisch, da angegeben wird, wie die folgenden RewriteRuleAnweisungen 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:

RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

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 RewriteRuleausgegangen, 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:

RewriteEngine On

##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER}                                   ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg)     $1.sf.$2

##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Wie Sie sehen, RewriteBasekö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.

RewriteRule ^/blog/(.*)$    /newblog/$1

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.

RewriteRule ^/blog/.*/(.*)$  /newblog/$1

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).

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$2

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.

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$1/$2

In diesem Fall verwenden wir $ 1 in der umgeschriebenen Zeichenfolge.

RewriteRule ^/blog/(20[0-9][0-9])/(.*)$   /newblog/$1/$2

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.

RewriteRule ^/blog/(20[0-9]{2})/(.*)$  /newblog/$1/$2

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.

RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html   /newblog/$1/$2.shtml

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.

RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html  /newblog/$1/$2.shtml

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.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

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 .

RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html  /newblog/$1/$2.shtml  [L]

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. Erlaubtjpgpassend 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 AddTypeRichtlinie.

Weißt du, wie ich sagte, dass dies RewriteCondnur für eine Regel gilt? Nun, das können Sie umgehen, indem Sie sie verketten.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html     [C]
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

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.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Dies kann durch Flags vereinfacht werden:

RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html   /newblog/$1/$2.shtml   [NC]

Einige Flags gelten auch für RewriteCond. Vor allem NoCase.

RewriteCond %{HTTP_REFERER}        ^https?://serverfault\.com(/|$)     [NC]

Entspricht "ServerFault.com"

sysadmin1138
quelle
9
Gut gemacht. [Füller]
EEAA
3
Sehr schöne mod_rewriteund reguläre Grundierung. +1.
Steven Montag
3
Manchmal ist es nützlich zu wissen, dass das RewriteCondtatsächlich verarbeitet wird, nachdem das RewriteRuleü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 ..."
Dennis Williamson
2
RewriteRule ^/blog/.*/(.*)$ /newblog/$1stimmt 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.
12.
1
@ sysadmin1138, ich denke, diese Antwort ist gut, aber es kann besser sein, wenn Sie die Flags E, N, NS, P, PT und S mit Beispielen
näher erläutern,
39

Was ist das grundlegende Format und die Struktur von mod_rewrite-Regeln?

Ich werde mich auf die ausgezeichnete Antwort von sysadmin1138 zu diesen Punkten beschränken.

Welche Form / Geschmack von regulären Ausdrücken muss ich beherrschen?

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.

Was sind die häufigsten Fehler / Fallstricke beim Schreiben von Umschreiberegeln?

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:

  • 500 - Internal Server Error (Interner Serverfehler) - Entfernen Sie die Windows-Steuerelemente für den Wagen in den Konfigurationsdateien (falls vorhanden). Stellen Sie sicher, dass mod_rewrite aktiviert ist ( IfModuleum dieses Szenario zu vermeiden, müssen Sie Anweisungen umbrechen)
  • Redirect-Schleife - Verwenden Sie RewriteLog und RewriteLogLevel, und kommentieren Sie Anweisungen aus, bis das Problem erkannt wird

Was ist eine gute Methode zum Testen und Überprüfen von mod_rewrite-Regeln?

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:

<?php
  var_dump($_SERVER);
?>

... 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 RewriteLogAnweisung von mod_rewrite , um Aktivitäten in einer Datei zu protokollieren und festzulegenRewriteLogLevel 3

Gibt es SEO- oder Performance-Auswirkungen von mod_rewrite-Regeln, auf die ich achten sollte?

AllowOverride allBeeinträchtigt die Serverleistung, da Apache .htaccessbei 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.

Gibt es Situationen, in denen mod_rewrite als das richtige Werkzeug für den Job erscheint, aber nicht?

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.

Was sind einige gängige Beispiele?

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).

danlefree
quelle
Danke für den AskApache Link. Es ist, wonach ich gesucht habe!
sica07
Der AskApache-Clown wird von der ASF offiziell nicht unterstützt. Vieles von dem, was er sagt, ist umstritten oder schlicht falsch.
12.
@adaptr Bitte teilen Sie die überlegenen Ressourcen, die Sie anscheinend kennen.
Danlefree
"Häufige Situationen, in denen mod_rewrite das richtige Werkzeug für den Job zu sein scheint, aber nicht?" - einfache Weiterleitungen, bei denen mod_rewrite noch nicht verwendet wird. Verwenden Sie stattdessen mod_alias Redirectoder RedirectMatch. Siehe auch die Apache-Dokumentation: Wann man mod_rewrite nicht benutzt
MrWhite
21

Wie 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_rewriteder Rest des Apache tatsächlich funktioniert und mit ihm interagiert Kern, also habe ich in den letzten Monaten Testfälle mit strace+ 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:

  • Einige Aspekte der Umschreiben sind gemeinsam Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess Verarbeitung jedoch
  • Bei der Stammkonfiguration (Serverkonfiguration, virtueller Host und Verzeichnis) unterscheidet sich die .htaccessVerarbeitung zum Teil erheblich von der bei PerDir ( ).
  • Schlimmer noch, da die PerDir-Verarbeitung den INTERNAL REDIRECT-Zyklus fast wahllos auslösen kann, müssen die Root-Konfigurationselemente darauf hingewiesen werden, dass eine solche PerDir-Verarbeitung dies auslösen kann.

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 .htaccessDateien, 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) .

    • Solche Benutzer haben verwenden .htaccess/ Perdir Verarbeitung , da es keine Alternative zur Verfügung steht.
    • Schlimmer noch, die Fähigkeiten solcher Benutzer (soweit sie die regexp-gesteuerte Ladder-Logik von mod_rewrite verwenden) sind im Allgemeinen deutlich geringer als bei erfahrenen Administratoren.
    • Apache und die Hosting-Anbieter bieten keine Unterstützung für Debugging / Diagnose. Die einzige Diagnoseinformation ist eine erfolgreiche Umleitung, eine Umleitung zum falschen URI. oder ein 404/500 Statuscode. Das macht sie verwirrt und hilflos.
    • Apache ist extrem schwach und erklärt, wie das Umschreiben für diesen Anwendungsfall funktioniert. Beispielsweise wird nicht klar erläutert, welche PerDir- .htaccessDatei 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 .htaccessBenutzer unterstützen soll , sind wir jedoch der Ansicht, dass wir Folgendes entwickeln und anbieten müssen:

  • Eine zusammenhängende Beschreibung der tatsächlichen Funktionsweise des Umschreibesystems bei der PerDir-Verarbeitung
  • Eine Reihe von Richtlinien / Best Practices zum Schreiben von .htaccessUmschreiberegeln
  • Ein einfacher webbasierter Parser für Umschreibeskripte, der den W3C-HTML-Parsern ähnelt, mit dem Benutzer jedoch Test-URIs oder Testvektoren derselben eingeben und ein sofortiges Protokoll des Umschreibelogikflusses abrufen können.
  • Tipps, wie Sie aus Ihren Regeln eine integrierte Diagnose erhalten (z. B.

    • Nutzen Sie [E=VAR:EXPR]die Tatsache, dass EXPRRü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:

      RewriteCond %{ENV:REDIRECT_STATUS} !=""
      RewriteRule .  -  [L]
      
TerryE
quelle
Dies ist gut dokumentiert. Warum, sagen Sie, erklärt die Dokumentation dies nicht?
12.
2
Alles, was Sie tun müssen, ist, die .htaccessThemen 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 .htaccessDateien 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. :-(
TerryE
Ich bin völlig einverstanden. "Wir müssen die Rewrite-Benutzer-Communitys in zwei Kategorien aufteilen und sie als völlig getrennt behandeln." Einige Benutzer verwenden Shared Hosting und müssen sich darauf verlassen .htaccess, was selbst für Experten furchtbar zerbrechlich, kompliziert und verwirrend ist. Ich habe immer noch Probleme.
Ryan
15

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:

RewriteMap MapName MapType:MapSource

Zum Beispiel:

RewriteMap examplemap txt:/path/to/file/map.txt

Sie können dann den Mapnamen für Konstrukte wie das folgende verwenden:

${examplemap:key}

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 ...

RewriteMap unescape int:unescape

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   café
RewriteRule ^/find/$         /find/1234? [L,R]

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 ...

Krist van Besien
quelle
Der letzte Satz ist nicht ganz richtig. Die mod_rewriteRegexp-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.
TerryE
12

Was sind die häufigsten Fehler / Fallstricke beim Schreiben von Umschreiberegeln?

Eine sehr einfache Falle ist das Umschreiben von URLs, die den scheinbaren Pfad ändern, z . B. von /base/1234/index.htmlnach /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 .

beldaz
quelle
1
Danke für den Link. Insbesondere bei der Arbeit mit anderen Teammitgliedern, die mit dem Umschreiben nicht vertraut sind, ist es für mich <base>am einfachsten, ein Tag hinzuzufügen und dennoch relative Pfade zu aktivieren.
Kontur