<-
Apache > HTTP-Server > Dokumentation > Version 2.5 > Rewrite

Umleitung und Neuzuordnung mit mod_rewrite

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

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.

Beachten Sie, dass viele dieser Beispiele nicht unverändert in Ihrer speziellen Serverkonfiguration funktionieren werden. Es ist daher wichtig, dass Sie sie verstehen, anstatt die Beispiele einfach auszuschneiden und in Ihre Konfiguration einzufügen.

Siehe auch

top

Von Alt zu Neu (intern)

Beschreibung:

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

Lösung:

Wir schreiben die alte URL intern auf die neue um, mit der folgenden Regel:

RewriteEngine  on
RewriteRule    "^/foo\.html$"  "/bar.html" [PT]
top

Umschreiben von Alt zu Neu (extern)

Beschreibung:

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.

Lösung:

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]
Diskussion

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"
top

Ressource auf einen anderen Server verschoben

Beschreibung:

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.

Lösung:

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/"
top

Von statisch zu dynamisch

Beschreibung:

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?

Lösung:

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]
top

Abwärtskompatibilität bei Änderung der Dateiendung

Beschreibung:

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?

Lösung:

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

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.

top

Kanonische Hostnamen

Beschreibung:
Das Ziel dieser Regel ist es, die Verwendung eines bestimmten Hostnamens zu erzwingen, anstelle anderer Hostnamen, die für den Zugriff auf dieselbe Website verwendet werden könnten. Wenn Sie beispielsweise die Verwendung von www.example.com anstelle von example.com erzwingen möchten, können Sie eine Variante des folgenden Rezepts verwenden.
Lösung:

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.

top

Suche nach Seiten in mehr als einem Verzeichnis

Beschreibung:

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.

Lösung:

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]
top

Umleitung auf geografisch verteilte Server

Beschreibung:

Wir haben zahlreiche Spiegelserver unserer Website und möchten Besucher auf denjenigen umleiten, der sich in dem Land befindet, in dem sie sich aufhalten.

Lösung:

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

Diskussion
Dieser Regelsatz setzt voraus, dass 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.

top

Kanonische URLs

Beschreibung:

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.

Lösung:

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]
Diskussion:
Dies sollte eigentlich mit Redirect- oder RedirectMatch-Direktiven erreicht werden:
RedirectMatch "^/(puppies|canines)/(.*)" "/dogs/$2"
top

Verschobenes DocumentRoot

Beschreibung:

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:

Lösung:

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.

top

Fallback-Ressource

Beschreibung:
Sie möchten, dass eine einzelne Ressource (beispielsweise eine bestimmte Datei wie index.php) alle Anfragen behandelt, die an ein bestimmtes Verzeichnis gerichtet sind, mit Ausnahme derjenigen, die an eine vorhandene Ressource wie ein Bild oder eine CSS-Datei gehen sollen.
Lösung:

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.

top

Query-String umschreiben

Beschreibung:
Sie möchten einen bestimmten Wert aus einem Query-String erfassen und ihn entweder ersetzen oder in eine andere Komponente der URL einbinden.
Lösungen:

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.

  • Diese Lösung entfernt den übereinstimmenden Schlüssel und Wert:
    # mykey=??? entfernen
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
    RewriteRule "(.*)"            "$1?%1%3"
  • Diese Lösung verwendet den erfassten Wert in der URL-Ersetzung und verwirft den Rest des ursprünglichen Query-Strings durch Anhängen eines '?':
    # Vom Query-String in PATH_INFO kopieren
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
    RewriteRule "(.*)"            "$1/products/%2/?" [PT]
  • Diese Lösung prüft den erfassten Wert in einer nachfolgenden Bedingung:
    # Den Wert von mykey im Query-String erfassen
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
    RewriteCond "%2"              !=not-so-secret-value
    RewriteRule "(.*)"            "-" [F]
  • Diese Lösung zeigt die Umkehrung der vorherigen und kopiert Pfadkomponenten (möglicherweise PATH_INFO) aus der URL in den Query-String.
    # Die gewünschte URL könnte /products/kitchen-sink sein, und das Skript erwartet
    # /path?products=kitchen-sink.
    RewriteRule "^/?path/([^/]+)/([^/]+)" "/path?$1=$2" [PT]

Verfügbare Sprachen:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn