Jörg Kruse Internet-
Programmierungen

Endlos-Weiterleitung

Bemerkt ein Browser, dass er endlos von einer URL auf die nächste weitergeleitet wird, bricht er nach einer bestimmten Anzahl von Weiterleitungen mit einer Fehlermeldung ab, so z.B. Firefox:

Fehler: Umleitungsfehler

Die aufgerufene Website leitet die Anfrage so um, dass sie nie beendet werden kann.

Dieses Problem kann manchmal auftreten, wenn Cookies deaktiviert oder abgelehnt werden.

… und Google Chrome:

Diese Seite funktioniert nicht
example.com hat Sie zu oft weitergeleitet.
Löschen Sie Ihre Cookies.
ERR_TOO_MANY_REDIRECTS

Beide Browser deuten in ihren Fehlermeldung auf eine Fehlerursache hin: Webseiten, die solange auf sich selbst weiterleiten, bis ein Cookie gesetzt ist. Browser, in denen Cookies deaktiviert sind, landen so in einer Endlosweiterleitung.

Darüber hinaus gibt es fehlerhafte Weiterleitungen, wie z.B. folgende Redirect-Direktive in der .htaccess Datei:


Redirect permantent /foo https://example.com/foo/bar

Dies ergibt ein Endlos-Weiterleitung https://example.com/foo -> https://example.com/foo/bar -> https://example.com/foo/bar/bar -> …

Besser wäre es hier mit mod_rewrite weiterzuleiten:


RewriteRule ^/?foo$ https://example.com/foo/bar [R=301,L]

Das Begrenzungszeichen $ sorgt dafür, dass im Pfad nach dem „/foo“ keine Zeichen mehr folgen dürfen, so dass https://example.com/foo/bar nicht mehr weitergeleitet wird.

In einem weiteren Beispiel werden mittels mod_rewrite statische URLs erzeugt, dabei wird z.B. example.com/foo intern umgeschrieben auf example.com/index.php?bar=foo:


RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.+)$ index.php?bar=$1

Darüber hinaus sollen umgekehrt Besucher und Suchmaschinen von den alten dynamischen URLs weitergeleitet werden zu den neuen statischen URLs:


RewriteCond %{QUERY_STRING} bar=(.+)
RewriteRule ^/?index\.php$ https://example.com/%1? [R=301]

Beides zusammen sorgt nun für eine Endlosweiterleitung.

Lösen lässt sich dies, indem zuerst die 301-Weiterleitung eingebaut wird und diese ein L(ast)-Flag erhält, welches bei einem Match die Ausführung folgender Regeln verhindert. Allerdings schlägt die Weiterleitung fälschlichweise in einem zweiten Durchlauf an, wenn in einem ersten Durchlauf durch die interne Umleitung der Query String bar=foo angehangen wird. Durch eine zusätzliche Prüfung auf den Request, welcher nicht durch andere Regeln geändert wird, kann man dies verhindern:


RewriteCond %{THE_REQUEST} \?bar=
RewriteCond %{QUERY_STRING} bar=(.+)
RewriteRule ^/?index\.php$ https://example.com/%1? [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.+)$ index.php?bar=$1

Da Browser alte 301-Weiterleitungen aus ihrem Cache laden, muss ggf. auch noch der Browser-Cache geleert werden, damit die Endlosweiterleitung behoben ist (siehe auch diesen Blogpost)