Apache: mod_rewrite aktivieren und nutzen

Gelesen bei AboutWebDesign.de
URL: http://www.aboutwebdesign.de/awd/content/1042302787.shtml

Das Apache-Modul mod_rewrite ermöglicht es, URLs intern "umzuschreiben" (rewrite). Heißt im Klartext: der Surfer greift auf eine (nicht real existierende) URL zu, der Apache verarbeitet diese anhand bestimmter Regeln, greift dann mit Hilfe des modifizierten Pfades auf eine Datei zu und schickt sie an den Browser. Der Client merkt davon nichts, kann davon gar nichts merken.

Ein Praxis-Beispiel


Ein etwas praktischeres Beispiel: Sie benutzen ein Warenkorb-System. Die URL, um alle Produkte der Haushaltsgeräte-Kategorie anzuzeigen, lautet warenkorb.php?action=show&kat=229. Wie unpraktisch:

Schöner wäre es, wenn die URL stattdessen liste_haushalt.html heißen würde. Alle drei oben genannten Nachteile würden sich erübrigen.

Genau darum geht es bei mod_rewrite: wenn liste_haushalt.html aufgerufen wird, soll ein interner Transformationsprozess gestartet werden, der diese URL zu warenkorb.php?action=show&kat=229 umschreibt. Zurückgeschickt werden sollen die Daten aber unter dem "Deckmantel" der ursprünglichen Anfrage, so dass es für den Client keine Möglichkeit gibt, Einblick in Ihre internen Prozesse zu nehmen.

Andere Techniken


Natürlich gibt es auch andere Techniken, so etwas zu erreichen. Sie könnten z.B. selbst eine Art Wrapper schreiben oder Ihre Warenkorb-Ausgaben mit SSI einbinden. Besonders letztere Alternative ist aber eigentlich ein statisches Verfahren, es artet, um beim Beispiel zu bleiben, bei zahlreichen Warenkorb-Kategorien in ziemlich viel Arbeit aus. Der selbstgeschriebene Wrapper dagegen gibt beim Aufruf nach außen zu erkennen, dass hier ein Script am Werk ist.

mod_rewrite umgeht all das, weil es dynamisch und direkt im Server-Kern wirksam ist.

Erste Schritte


Im Folgenden werden wir uns daher damit beschäftigen, Ihnen dieses wunderbare Modul etwas näher zu bringen. Dafür benötigen Sie:

mod_rewrite laden


Öffnen Sie nun die Apache-Konfigurationsdatei httpd.conf und aktivieren Sie die folgenden Zeilen, indem Sie die führenden Rauten entfernen (möglicherweise, je nach Ihrer Konfiguration, müssen Sie die Zeilen auch hinzufügen bzw. modifizieren):

#LoadModule rewrite_module modules/mod_rewrite.so
#AddModule mod_rewrite.c


Nach einem Neustart des Apache ist das Modul zwar geladen, arbeitet aber noch nicht.

mod_rewrite starten


Dazu müssen Sie noch etwas mehr Code in die httpd.conf hinzufügen:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^/liste_haushalt.html$ /warenkorb.php?action=show&kat=229
</IfModule>


Die erste Zeile aktiviert die "RewriteEngine", die zweite definiert eine erste Regel für das URL-Umschreiben. Vor Inkrafttreten ist wieder ein Neustart des Apache nötig.

Übrigens lassen sich solche Direktiven für das mod_rewrite-Modul auch im Kontext eines virtuellen Servers definieren, aber das würde hier zu weit führen.

Die Regeln sind das eigentliche "Arbeitspferd" des mod_rewrite-Moduls. Deshalb werden wir uns nun etwas detaillierter mit ihnen beschäftigen:

Die erste Transformations-Regel


Sehen Sie sich die erste Transformations-Regel noch einmal an:

RewriteRule ^/liste_haushalt.html$ /warenkorb.php?action=show&kat=229

Was geschieht hier? Regeln sind nach dem Schema RewriteRule Suchmuster Ersetzung Optionen aufgebaut. Optionen werden in unserem Beispiel noch nicht verwendet.

Ersetzungen funktionieren nach einem einfachen Schema: es wird versucht, das Muster auf die angeforderte URL anzuwenden. Wenn das klappt, wird die URL zurückgeliefert, die sich durch Ersetzung ergibt. Der Client wird dabei, um das noch ein letztes Mal zu betonen, "ausgetrickst": er wird während des gesamten Vorgangs der Meinung sein, die ursprüngliche URL angefordert und auch bekommen zu haben.

Die Reihenfolge der Transformations-Regeln ist wichtig: es kann durchaus vorkommen, dass dem Muster nach mehr als eine Regel auf eine angeforderte URL passt. In diesem Fall wird die am weitesten oben stehende Regel zuerst verwendet, dann die weiter unten stehenden!

Das Muster


Das Muster ist ein regulärer Ausdruck. Reguläre Ausdrücke sind eine Art Suchfunktion. Mit ihnen kann man feststellen, ob eine Zeichenkette so aussieht, wie man sie gerne hätte.

Reguläre Ausdrücke sehen, wenn man sie nicht kennt, ziemlich kompliziert aus - komplizierter, als sie wirklich sind, denn im Internet gibt es genügend Informationen zum Thema, z.B. im "Reguläre Ausdrücke"-Abschnitt bei SelfHTML.

Unser im Beispiel verwendet Ausdruck ist sehr simpel: Das ^-Zeichen steht für "Anfang der Zeichenkette, das $ für "Ende der Zeichenkette". Die dazwischen stehenden Informationen sind keine Sonderzeichen, werden also so verarbeitet, wie sie da stehen. Dieser reguläre Ausdruck erfasst also genau die Zeichenkette /liste_haushalt.html. Jede andere Zeichenkette würde als nicht passend zurückgewiesen und die Transformations-Regel nicht angewandt.

Die Ersetzung


Im Ersetzungs-Abschnitt können Sie auf das Muster zurückgreifen, aber dazu später mehr. In unserem Fall enthält der Ersetzungs-Abschnitt keine Sonderzeichen, wird also genau so genommen, wie er in der Datei steht. Bisher also nicht allzu schwierig, nicht wahr?

Ein anspruchsvolleres Beispiel


Wie Sie vielleicht schon ahnen, liegt die eigentliche Magie von mod_rewrite in den regulären Ausdrücken: sie gelten als das beste Werkzeug, um Text zu erkennen. Deshalb nun eine etwas komplexere Regel (Neustart erforderlich!):


RewriteRule ^/kategorien/([0-9]+)$ /warenkorb.php?action=show&kat=$1


Eine URL wie /kategorien/321 wird dadurch übersetzt in /warenkorb.php?action=show&kat=321.

Wie funktioniert das? Wir erkennen URLs, bei denen /kategorien/ am Anfang steht und eine beliebige Anzahl von Zahlen dahinter. Letzteres erreichen wir mit dem Ausdruck ([0-9]+). In Einzelteile zerbröselt:

Jetzt aber genug der regulären Ausdrücke - allein über sie könnte man bequem ein dickes Buch schreiben, und hier geht es schließlich um mod_rewrite.

Und im Ersetzungs-Teil? Wir sorgen einfach nur dafür, dass der Zahlen-Teil der URL als Parameter an unser PHP-Script übergeben wird, ohne dass jemand etwas davon merkt.

Herzlichen Glückwunsch! Sie sind nun so weit, mod_rewrite produktiv einsetzen zu können. Aber vielleicht wollen Sie ja noch etwas mehr wissen?

Komplexere Techniken


Die Optionen


Wir hatten zuvor einen Options-Abschnitt der Regel-Definitionen erwähnt, ohne näher auf ihn einzugehen.

Die folgende Regel z.B. führt dazu, dass bei Zugriff auf /abc ein HTTP-Fehler 403 ("Forbidden", kein Zugriff) zurückgeschickt wird.


RewriteRule ^/abc$ /abc [forbidden]


Anstelle des forbidden könnten Sie auch einsetzen:

So beispielsweise könnten Sie eine Weiterleitung auf die Webdesign-Referenz realisieren:

RewriteRule ^/wdref$ http://www.webdesign-referenz.de [redirect,last]

Bedingungen definieren


Um noch besser angepasste Regeln zu erstellen, können Sie Bedingungen verwenden: eine Bedingung gilt immer für die nächste folgende Transformations-Regel. Nur, wenn die Bedingung ein "OK" zurückliefert, wird die Regel auch endgültig angewandt.

Interessanterweise ist es möglich, mehrere Bedingungen auf eine Regel anzuwenden. Die Regeln werden dann mit einem logischen UND zusammengefasst, d.h. alle müssen zutreffen - dazu weiter unten ein Beispiel.

Rein technisch ist es übrigens andersherum: erst wird überprüft, ob das Muster einer Regel zutrifft, dann wird die zugehörige Bedingung ausgewertet. Aber das soll uns nicht weiter stören - hauptsache, es funktioniert.

Die Syntax für eine Bedingung ist simpel:

RewriteCond Testobjekt Bedingung

Testobjekt ist das Objekt der Bedingung, also beispielsweise die Variable, die getestet werden soll. Hier können diverse Werte eingesetzt werden, z.B. fast alle CGI-Umgebungsvariablen, allerdings oft in etwas anderer Schreibweise. Eine komplette Liste akzeptierter Variablen finden Sie in der Dokumentation zu RewriteCond.
W
Die Bedingung definiert dann einen Test, der auf das Textobjekt angewandt wird. Sie können hier z.B. reguläre Ausdrücke und mathematische Vergleichsoperatoren verwenden.

Beispiel 1


Genug der Theorie! Mit folgendem Code können Sie Benutzer, die von AboutWebDesign.de kommen, besonders begrüßen:

RewriteCond %{HTTP_REFERER} ^http://www.aboutwebdesign.de.de/.*$
RewriteRule ^/.+$ /index-awd.html [last]

Beispiel 2


Oder wie wäre, verschiedenen Browsern verschiedene Homepages zu liefern? Folgendes Beispiel stammt aus der mod_rewrite-Dokumentation:

RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*
RewriteRule ^/$ /homepage.max.html [L]

RewriteCond %{HTTP_USER_AGENT} ^Lynx.*
RewriteRule ^/$ /homepage.min.html [L]

RewriteRule ^/$ /homepage.std.html [L]


Beispiel 3


Und dieser Code verhindert, dass andere Sites Bilder von Ihrem Server direkt einbinden:

RewriteCond %{HTTP_REFERER} !^http://ihr-server.de
RewriteCond %{HTTP_REFERER} !^http://www.ihr-server.de
RewriteCond %{REQUEST_URI} !^.+ban_image.+$

RewriteRule ^.+\.(gif|GIF|jpg|JPG|jpeg|JPEG)$ http://www.ihr-server.de/ban-image.gif [redirect,last]


ban-image.gif ist die Datei, die angezeigt wird, wenn dennoch eine direkte Einbindung versucht wird. Ein großes Stoppschild wäre hier angemessen.

Am Code gut zu sehen:

Fazit


mod_rewrite ist ein großartiges Tool, das Ihre Site besser machen und Ihnen Arbeit sparen kann. Wenn Sie tiefer in die Materie einsteigen wollen, finden Sie in der offiziellen Dokumentation genug Stoff. Aber auch eine Suche nach "mod_rewrite" in Ihrer bevorzugten Suchmaschine wird genug liefern, um sich tagelang zu beschäftigen.

Zum Abschluss noch ein Tipp: bevor Sie mod_rewrite irgendwo einsetzen, wo direkter Kontakt mit Ihren Kunden/Surfern besteht, probieren Sie Ihre Ideen erst auf einem Test-Server aus. Dafür können Sie sich z.B. Apache auf Ihrem Windows-Rechner installieren.