Apache HTTP Server Version 2.5

Dieses Dokument ergänzt die mod_rewrite
Referenzdokumentation. Es beschreibt,
wie Sie mod_rewrite verwenden können, um Anfragen
umzuleiten und neu zuzuordnen. Dies beinhaltet viele Beispiele für gängige
Verwendungen von mod_rewrite, einschließlich detaillierter
Beschreibungen, wie jedes einzelne funktioniert.
Von Alt zu Neu (intern)
Umschreiben von Alt zu Neu (extern)
Ressource auf einen anderen Server verschoben
Von statisch zu dynamisch
Abwärtskompatibilität bei Änderung der Dateiendung
Kanonische Hostnamen
Suche nach Seiten in mehr als einem Verzeichnis
Umleitung auf geografisch verteilte Server
Kanonische URLs
Verschobenes DocumentRoot
Fallback-Ressource
Query-String umschreibenAngenommen, wir haben kürzlich die Seite
foo.html in bar.html umbenannt und
möchten nun die alte URL aus Gründen der Abwärtskompatibilität
weiterhin bereitstellen. Dabei sollen die Benutzer der alten URL
jedoch nicht bemerken, dass die Seite umbenannt wurde - das heißt,
die Adresse soll sich in ihrem Browser nicht ändern.
Wir schreiben die alte URL intern auf die neue um, mit der folgenden Regel:
RewriteEngine on RewriteRule "^/foo\.html$" "/bar.html" [PT]
Angenommen erneut, dass wir kürzlich die Seite
foo.html in bar.html umbenannt haben und
nun die alte URL aus Gründen der Abwärtskompatibilität weiterhin
bereitstellen möchten. Diesmal möchten wir aber, dass die Benutzer
der alten URL auf die neue hingewiesen werden, d.h. die
Adresszeile ihres Browsers soll sich ebenfalls ändern.
Wir erzwingen eine HTTP-Umleitung auf die neue URL, was zu einer Änderung der Browser-Adresszeile und damit der Ansicht der Benutzer führt:
RewriteEngine on RewriteRule "^/foo\.html$" "bar.html" [R]
In diesem Beispiel können wir im Gegensatz zum
internen Beispiel oben einfach die
Redirect-Direktive verwenden. mod_rewrite wurde in
diesem früheren Beispiel verwendet, um die Umleitung vor dem Client
zu verbergen:
Redirect "/foo.html" "/bar.html"
Wenn eine Ressource auf einen anderen Server verschoben wurde, möchten Sie möglicherweise, dass URLs für eine gewisse Zeit weiterhin auf dem alten Server funktionieren, während die Benutzer ihre Lesezeichen aktualisieren.
Sie können mod_rewrite verwenden, um diese URLs
auf den neuen Server umzuleiten, aber Sie könnten auch die Redirect-
oder RedirectMatch-Direktive in Betracht ziehen.
#Mit mod_rewrite RewriteEngine on RewriteRule "^/docs/(.+)" "http://new.example.com/docs/$1" [R,L]
#Mit RedirectMatch RedirectMatch "^/docs/(.*)" "http://new.example.com/docs/$1"
#Mit Redirect Redirect "/docs/" "http://new.example.com/docs/"
Wie können wir eine statische Seite
foo.html nahtlos in eine dynamische Variante
foo.cgi umwandeln, d.h. ohne dass der
Browser/Benutzer es bemerkt?
Wir schreiben die URL einfach auf das CGI-Skript um und
erzwingen, dass der Handler cgi-script ist,
damit es als CGI-Programm ausgeführt wird. So führt eine Anfrage
an /~quux/foo.html intern zum Aufruf von
/~quux/foo.cgi.
RewriteEngine on RewriteBase "/~quux/" RewriteRule "^foo\.html$" "foo.cgi" [H=cgi-script]
Wie können wir URLs abwärtskompatibel machen (virtuell weiterhin
existierend), nachdem document.YYYY zu
document.XXXX migriert wurde, z.B. nach der Konvertierung
einer Reihe von .html-Dateien nach .php?
Die URL wird nur dann von der alten auf die neue Endung umgeschrieben, wenn die Zieldatei mit der neuen Endung existiert und die Originaldatei mit der alten Endung nicht existiert. Andernfalls bleibt die URL unverändert.
# Abwärtskompatibilitäts-Regelsatz für
# Umschreibung von document.html zu document.php
# wenn und nur wenn document.php existiert
<Directory "/var/www/htdocs">
RewriteEngine on
RewriteBase "/var/www/htdocs"
RewriteCond "$1.php" -f
RewriteCond "$1.html" !-f
RewriteRule "^(.*).html$" "$1.php"
</Directory>
Dieses Beispiel nutzt eine oft übersehene Funktion von
mod_rewrite, indem es die Ausführungsreihenfolge des
Regelsatzes ausnutzt. Insbesondere wertet mod_rewrite
die linke Seite der RewriteRule aus, bevor es die
RewriteCond-Direktiven auswertet. Folglich ist $1 bereits definiert,
wenn die RewriteCond-Direktiven ausgewertet werden. Dies ermöglicht
es uns, die Existenz der Original- (document.html) und
Zieldatei (document.php) unter Verwendung desselben
Basisdateinamens zu prüfen.
Dieser Regelsatz ist für die Verwendung im Verzeichniskontext
(in einem <Directory>-Block oder in einer .htaccess-Datei)
konzipiert, sodass die -f-Prüfungen im korrekten
Verzeichnispfad suchen. Möglicherweise müssen Sie eine RewriteBase-Direktive setzen, um das
Verzeichnis anzugeben, in dem Sie arbeiten.
Der allerbeste Weg, dies zu lösen, verwendet gar nicht mod_rewrite,
sondern die Redirect-Direktive
in einem virtuellen Host für den nicht-kanonischen Hostnamen.
<VirtualHost *:80> ServerName undesired.example.com ServerAlias example.com notthis.example.com Redirect "/" "http://www.example.com/" </VirtualHost> <VirtualHost *:80> ServerName www.example.com </VirtualHost>
Alternativ können Sie dies mit der
<If>-Direktive
erreichen: (ab Version 2.4)
<If "%{HTTP_HOST} != 'www.example.com'">
Redirect "/" "http://www.example.com/"
</If>
Oder, um beispielsweise einen Teil Ihrer Website auf HTTPS umzuleiten, könnten Sie Folgendes tun:
<If "%{SERVER_PROTOCOL} != 'HTTPS'">
Redirect "/admin/" "https://www.example.com/admin/"
</If>
Wenn Sie aus irgendeinem Grund dennoch mod_rewrite
verwenden möchten - zum Beispiel, wenn Sie dies mit einer größeren Menge
von RewriteRules benötigen - können Sie eines der folgenden Rezepte
verwenden.
Für Websites, die auf einem anderen Port als 80 laufen:
RewriteCond "%{HTTP_HOST}" "!^www\.example\.com" [NC]
RewriteCond "%{HTTP_HOST}" "!^$"
RewriteCond "%{SERVER_PORT}" "!^80$"
RewriteRule "^/?(.*)" "http://www.example.com:%{SERVER_PORT}/$1" [L,R,NE]
Und für eine Website auf Port 80:
RewriteCond "%{HTTP_HOST}" "!^www\.example\.com" [NC]
RewriteCond "%{HTTP_HOST}" "!^$"
RewriteRule "^/?(.*)" "http://www.example.com/$1" [L,R,NE]
Wenn Sie dies generisch für alle Domainnamen tun möchten - das heißt, wenn Sie example.com für alle möglichen Werte von example.com auf www.example.com umleiten möchten, können Sie das folgende Rezept verwenden:
RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
RewriteCond "%{HTTP_HOST}" "!^$"
RewriteRule "^/?(.*)" "http://www.%{HTTP_HOST}/$1" [L,R,NE]
Diese Regelsätze funktionieren sowohl in Ihrer
Hauptserverkonfigurationsdatei als auch in einer .htaccess-Datei,
die im DocumentRoot des Servers
abgelegt wird.
Eine bestimmte Ressource könnte an einem von mehreren Orten existieren, und wir möchten an diesen Orten nach der Ressource suchen, wenn sie angefordert wird. Vielleicht haben wir kürzlich unsere Verzeichnisstruktur umorganisiert und Inhalte auf mehrere Orte verteilt.
Der folgende Regelsatz sucht in zwei Verzeichnissen nach der Ressource und versucht, falls sie an keinem der beiden Orte gefunden wird, sie einfach vom angeforderten Ort auszuliefern.
RewriteEngine on
# zuerst versuchen, es in dir1/ zu finden...
# ...und wenn gefunden, anhalten und zufrieden sein:
RewriteCond "%{DOCUMENT_ROOT}/dir1/%{REQUEST_URI}" -f
RewriteRule "^(.+)" "%{DOCUMENT_ROOT}/dir1/$1" [L]
# dann versuchen, es in dir2/ zu finden...
# ...und wenn gefunden, anhalten und zufrieden sein:
RewriteCond "%{DOCUMENT_ROOT}/dir2/%{REQUEST_URI}" -f
RewriteRule "^(.+)" "%{DOCUMENT_ROOT}/dir2/$1" [L]
# sonst weiter zu anderen Alias- oder ScriptAlias-Direktiven usw.
RewriteRule "^" "-" [PT]
Wir haben zahlreiche Spiegelserver unserer Website und möchten Besucher auf denjenigen umleiten, der sich in dem Land befindet, in dem sie sich aufhalten.
Anhand des Hostnamens des anfragenden Clients bestimmen wir, aus welchem Land er kommt. Wenn wir keine Auflösung seiner IP-Adresse durchführen können, greifen wir auf einen Standardserver zurück.
Wir verwenden eine RewriteMap-Direktive,
um eine Liste der gewünschten Server zu erstellen.
HostnameLookups on
RewriteEngine on
RewriteMap multiplex "txt:/path/to/map.mirrors"
RewriteCond "%{REMOTE_HOST}" "([a-z]+)$" [NC]
RewriteRule "^/(.*)$" "${multiplex:%1|http://www.example.com/}$1" [R,L]
## map.mirrors -- Multiplexing-Map
de http://www.example.de/
uk http://www.example.uk/
com http://www.example.com/
##EOF##
HostNameLookups auf on
gesetzt ist, was einen erheblichen Leistungseinbruch bedeuten kann.Die RewriteCond-Direktive
erfasst den letzten Teil des Hostnamens des anfragenden Clients - den
Ländercode - und die nachfolgende RewriteRule verwendet diesen Wert,
um den entsprechenden Spiegelhost in der Map-Datei nachzuschlagen.
Auf manchen Webservern gibt es mehr als eine URL für eine Ressource. Normalerweise gibt es kanonische URLs (die tatsächlich verwendet und verteilt werden) und solche, die nur Abkürzungen, interne Adressen usw. sind. Unabhängig davon, welche URL der Benutzer mit der Anfrage angegeben hat, sollte er schließlich die kanonische URL in der Adresszeile seines Browsers sehen.
Wir führen eine externe HTTP-Umleitung für alle nicht-kanonischen
URLs durch, um sie in der Adressanzeige des Browsers und für alle
nachfolgenden Anfragen zu korrigieren. Im folgenden Beispiel-Regelsatz
ersetzen wir /puppies und /canines
durch die kanonische URL /dogs.
RewriteRule "^/(puppies|canines)/(.*)" "/dogs/$2" [R]
RedirectMatch "^/(puppies|canines)/(.*)" "/dogs/$2"
DocumentRoot ¶Normalerweise entspricht das DocumentRoot
des Webservers direkt der URL "/". Aber oft sind diese Daten
nicht wirklich von höchster Priorität. Beispielsweise möchten Sie
vielleicht, dass Besucher beim ersten Betreten einer Website in ein
bestimmtes Unterverzeichnis /about/ geleitet werden. Dies
kann mit dem folgenden Regelsatz erreicht werden:
Wir leiten die URL / nach
/about/ um:
RewriteEngine on RewriteRule "^/$" "/about/" [R]
Beachten Sie, dass dies auch mit der RedirectMatch-Direktive gehandhabt werden
kann:
RedirectMatch "^/$" "http://example.com/about/"
Beachten Sie auch, dass das Beispiel nur die Stamm-URL umschreibt.
Das heißt, es schreibt eine Anfrage für http://example.com/
um, aber nicht eine Anfrage für http://example.com/page.html.
Wenn Sie tatsächlich Ihr Document Root geändert haben - das heißt, wenn
alle Ihre Inhalte tatsächlich in diesem Unterverzeichnis
liegen - ist es wesentlich besser, einfach Ihre
DocumentRoot-Direktive zu ändern
oder alle Inhalte ein Verzeichnis nach oben zu verschieben, anstatt URLs
umzuschreiben.
Ab Version 2.2.16 sollten Sie hierfür die FallbackResource-Direktive verwenden:
<Directory "/var/www/my_blog"> FallbackResource index.php </Directory>
In älteren Versionen von Apache oder wenn Ihre Anforderungen komplizierter sind, können Sie eine Variante des folgenden Umschreibungssatzes verwenden, um dasselbe zu erreichen:
<Directory "/var/www/my_blog">
RewriteBase "/my_blog"
RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-f
RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-d
RewriteRule "^" "index.php" [PT]
</Directory>
Wenn Sie andererseits die angeforderte URI als Query-String-Argument an index.php übergeben möchten, können Sie diese RewriteRule ersetzen durch:
RewriteRule "(.*)" "index.php?$1" [PT,QSA]
Beachten Sie, dass diese Regelsätze sowohl in einer
.htaccess-Datei als auch in einem <Directory>-Block
verwendet werden können.
Viele der Lösungen in diesem Abschnitt verwenden dieselbe Bedingung, die den übereinstimmenden Wert in der Rückreferenz %2 belässt. %1 ist der Anfang des Query-Strings (bis zum interessierenden Schlüssel) und %3 ist der Rest. Diese Bedingung ist etwas komplex, um Flexibilität zu gewährleisten und doppelte '&&' in den Ersetzungen zu vermeiden.
# mykey=??? entfernen
RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
RewriteRule "(.*)" "$1?%1%3"
# Vom Query-String in PATH_INFO kopieren
RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
RewriteRule "(.*)" "$1/products/%2/?" [PT]
# Den Wert von mykey im Query-String erfassen
RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
RewriteCond "%2" !=not-so-secret-value
RewriteRule "(.*)" "-" [F]
# Die gewünschte URL könnte /products/kitchen-sink sein, und das Skript erwartet # /path?products=kitchen-sink. RewriteRule "^/?path/([^/]+)/([^/]+)" "/path?$1=$2" [PT]