Chromiums Beschreibung dieser Fehlermeldung ist bewundernswert prägnant: “Das Laden einer URL hat zu vielen Umleitungen geführt.” Der Browser folgte einer Kette von Umleitungen, die Kette endete nicht, und irgendwann stellte er das Folgen ein.

Die Nummer, bei der der Browser stoppt, kommt aus der Fetch Standard, die dazu unmissverständlich ist: wenn die Umleitungsanzahl der Anfrage 20 beträgt, wird ein Netzwerkfehler zurückgegeben. Also zwanzig Sprünge, und dann ist die Seite, die Sie sehen, die des Browsers, nicht Ihre.

Was diese Fehlermeldung einer eigenen Erklärung wert macht, ist nicht der Mechanismus, der offensichtlich ist. Es ist, dass eine Umleitungsschleife fast nie eine Sache ist, die kaputt ist. Es sind zwei Dinge, die jeweils genau so funktionieren, wie sie konfiguriert sind, und sich über etwas uneinig sind, das keiner von beiden sehen kann.

Der Klassiker, der ein Streit über HTTPS ist

Sie setzen einen CDN oder einen Load Balancer vor Ihre Anwendung. Er terminiert TLS, das ist seine Aufgabe, und leitet die Anfrage zu Ihrem Origin über einfaches HTTP weiter, was normal und normalerweise beabsichtigt ist.

Ihre Anwendung hat eine Regel, die besagt: Wenn diese Anfrage nicht HTTPS ist, leite sie auf HTTPS um. Auch richtig, und auf einem Server ohne Proxy davor ist das genau das Richtige.

Setzen Sie sie nun zusammen. Der Browser fragt nach https://example.com. Der CDN terminiert das TLS und leitet http://example.com an Ihre App weiter. Ihre App sieht einfaches HTTP, tut das Vernünftige und antwortet “leite um zu https://example.com”. Der Browser gehorcht. Der CDN terminiert TLS und leitet HTTP weiter. Zwanzig Mal, dann gibt der Browser auf.

Keine der beiden Komponenten ist für sich allein fehlkonfiguriert. Die Anwendung erzwingt HTTPS. Der Proxy terminiert TLS. Der Fehler liegt in der Lücke zwischen ihnen, deshalb können beide Teams auf ihre eigene Konfiguration schauen und richtig zu dem Ergebnis kommen, dass sie in Ordnung ist.

Der Fix ist, dass die App aufhören muss, die falsche Frage zu stellen. Statt “war diese Anfrage HTTPS”, muss sie fragen “war die ursprüngliche Anfrage HTTPS”, das ist das, wofür der Header X-Forwarded-Proto da ist. Die meisten Frameworks haben eine Einstellung, um diesem Header von einem bekannten Proxy zu vertrauen, und sie ist normalerweise aus gutem Grund standardmäßig ausgeschaltet: Ein Header, den jeder setzen kann, ist keine Beweis, es sei denn, Sie wissen, wer ihn gesetzt hat.

Die gleiche Form, dreimal mehr

Wenn Sie erst mal das Muster sehen, sind die anderen häufigen Schleifen die gleiche Geschichte mit anderen Worten.

www gegen den Apex. Eine Schicht leitet example.com zu www.example.com um. Eine andere, die später hinzugefügt oder von jemand anderem hinzugefügt wurde, leitet www zurück zum Apex. Jede Regel ist zu rechtfertigen. Das Paar ist eine Schleife.

Der Schrägstrich. Ihr Webserver leitet /about zu /about/ um. Der Router des Frameworks leitet /about/ zu /about um. Beide erzwingen eine kanonische Form. Sie sind sich uneinig, welche die kanonische ist.

Die Login-Schleife, das ist die, die echte Benutzer erreicht. Die App sieht keine gültige Session, also leitet sie zu /login um. Die Login-Seite prüft das Session-Cookie, glaubt, der Benutzer ist angemeldet, und leitet zur App um. Immer und immer wieder.

Dieses letzte ist worth zu betonen, denn die Ursache ist normalerweise das Cookie, das nicht funktioniert statt die Umleitung Regeln falsch sind: ein Secure-Cookie auf einer Seite, die über HTTP bedient wird, ein SameSite=None-Cookie ohne Secure, ein Cookie auf www.example.com eingestellt, das auf example.com gelesen wird, oder ein Browser, der konfiguriert ist, um Third-Party-Cookies in einem eingebetteten Kontext abzulehnen. Die Umleitungslogik ist durchgehend richtig. Sie handelt auf einer Session, die nie beibehalten wurde.

Schwach
"Ihre Login-Seite steckt in einer Schleife fest. Sie lädt sich einfach immer wieder neu."
Besser
ERR_TOO_MANY_REDIRECTS auf /login, nur in einem privaten Fenster, nur nachdem ich mich ab- und wieder anmelde. Funktioniert in meinem normalen Fenster. Kette ist /app → /login → /app.

Warum dieses besonders schwer zu sehen von innen ist

Eine Umleitungsschleife ist oft spezifisch für einen Zustand, in dem Sie nicht sind.

Wenn es die Login-Schleife ist, ist Ihr Cookie bereits eingestellt und funktioniert, die Seite verhält sich also perfekt für Sie und führt Schleifen für jeden aus, der neu ankommt. Wenn es eine www-Regel ist, die jemand letzte Woche hinzugefügt hat, führt sie nur für Menschen Schleifen durch, die die andere Hostname eingegeben haben. Wenn es von einem Cookie abhängt, das der Browser ablehnt, reproduziert es sich in einem privaten Fenster und nirgends sonst.

Und die offensichtliche Überprüfung vermisst es. curl -I https://example.com zeigt Ihnen eine Antwort, die gut aussehen wird, ein perfekt vernünftiger 301 mit einem Location-Header. Nichts daran deutet darauf hin, dass die Kette nie endet. Was Sie wollen ist, der ganzen Kette zu folgen:

curl -sIL -o /dev/null -w '%{url_effective} %{http_code}\n' https://example.com
curl -sI https://example.com | grep -i '^location'

Oder öffnen Sie die Netzwerk-Registerkarte mit Log beibehalten angekreuzt, das ist der einzige Weg, um die früheren Sprünge zu behalten, statt sie bei jeder Navigation zu löschen. Die Kette ist die Diagnose: Lesen Sie den Location-Header bei jedem Schritt, und Sie können normalerweise die beiden Regeln sehen, die sich binnen drei Sprünge streiten.

Session Replay

Kostenlose Chrome-Erweiterung. Ein Klick auf die Seite, die sich falsch verhält, erfasst den Screenshot, die Konsole und das Netzwerk-Protokoll, und gibt Ihnen einen Link zum Einfügen in das Ticket.

Erweiterung abrufen

Eine Sache über 301 wert zu wissen, bevor Sie es verwenden

Ein 301 ist nicht einfach ein 302, das es mehr bedeutet.

MDN ist spezifisch auf einer Folge, die Leute überrascht: In der Fetch Standard verwendet ein User Agent, der einen 301 als Antwort auf einen POST erhält, GET für die umgeleitete Anfrage. Ihre Formularabsendung wird zu GET, der Body ist weg, und der Fehler sieht nichts wie ein Umleitungsproblem aus. Wenn Sie die Methode beibehalten müssen, ist 308 die, die es verbietet, sie zu ändern.

Die allgemeine Regel ist langweiliger und nützlicher: Greifen Sie zu 302 oder 307, während Sie immer noch herausfinden, was die kanonische URL ist, und verwenden Sie 301 oder 308, wenn Sie sicher sind. Eine permanente Umleitung ist eine Behauptung, und Behauptungen sind viel leichter zu machen als zurückzuziehen.

Was man davon mitnehmen sollte

ERR_TOO_MANY_REDIRECTS bedeutet zwanzig Sprünge ohne Ende, und das Ende fehlt, weil zwei Regeln nicht einig sind, nicht weil eine kaputt ist.

Beginnen Sie also nicht damit, nach der kaputten Regel zu suchen. Beginnen Sie damit, jede Schicht aufzulisten, der es erlaubt ist, eine Umleitung zu geben: den CDN, den Load Balancer, den Webserver, das Framework, die Anwendung und alles, was ein Plugin hinzugefügt hat, ohne es jemandem zu sagen. Dann lesen Sie die Kette, einen Location-Header nach dem anderen, und finden Sie die beiden, die streiten.

Und wenn es sich für Sie nicht reproduziert, ist das eine Information, kein Hindernis. Das bedeutet, dass die Schleife von einem Zustand abhängt, den Sie bereits überwunden haben, und der schnellste Weg dorthin ist ein privates Fenster, ein anderer Hostname, oder das vollständige Bild von dem, was der Browser tatsächlich erhalten hat von jemandem, für den es gerade fehlschlägt.