Der Fehler sieht so aus. Eine Integration schickt ein POST an Ihren Endpunkt. Der Endpunkt funktioniert, die Route existiert, von Hand lässt sich alles nachvollziehen. In den Logs steht aber ein GET auf eine Route, die nur POST annimmt, beantwortet mit 404 oder 405.
Die Ursache ist fast immer dieselbe: Zwischen Client und Endpunkt liegt eine Weiterleitung mit 301 oder 302. Und diese Codes verpflichten den Client nicht, die Methode beizubehalten.
Nachprüfen lässt sich das in zehn Sekunden:
curl -sS -o /dev/null -L -d 'test=1' \
-w 'Methode nach der Weiterleitung: %{method}\n' \
'https://httpbingo.org/redirect-to?url=/anything&status_code=301'
Ausgabe: Methode nach der Weiterleitung: GET. Der Request-Body geht gleich mit verloren.
Ersetzen Sie 301 im selben Befehl durch 308, und Sie erhalten POST. Der einzige Unterschied ist der Statuscode.
Fünf Codes, zwei Eigenschaften
Weiterleitungen unterscheiden sich entlang zweier unabhängiger Achsen: dauerhaft oder temporär, und ob die Anfragemethode erhalten bleibt.
| Code | Name | Dauerhaftigkeit | Methode bleibt |
|---|---|---|---|
| 301 | Moved Permanently | dauerhaft | nein |
| 302 | Found | temporär | nein |
| 303 | See Other | — | nein, immer GET |
| 307 | Temporary Redirect | temporär | ja |
| 308 | Permanent Redirect | dauerhaft | ja |
Beachten Sie die Symmetrie: 307 ist ein 302 mit Methodengarantie, 308 ein 301 mit Methodengarantie.
Woher die Verwirrung kommt
Formal hat die Spezifikation nie verlangt, die Methode bei 301 und 302 zu ändern. Frühe Browser und Clients taten aber genau das, und als die Diskrepanz auffiel, arbeitete das gesamte Web bereits so.
Also wurde das Verhalten als zulässig festgeschrieben: RFC 9110, die aktuelle Spezifikation der HTTP-Semantik, erlaubt dem Client, bei 301 und 302 POST durch GET zu ersetzen. Erlaubt, aber verlangt es nicht — das Verhalten bleibt also dem Client überlassen und ist nicht verlässlich.
Um eine eindeutige Option zu schaffen, wurden 307 und 308 eingeführt. Bei ihnen ist ein Methodenwechsel verboten: Der Client muss die Anfrage mit derselben Methode und demselben Body wiederholen. Code 308 ist in einem eigenen RFC 7538 definiert, eine Referenzbeschreibung findet sich in der MDN-Dokumentation.
Die praktische Schlussfolgerung: 301 und 302 sind nur dort sicher, wo die Anfrage mit Gewissheit ein GET ist. Überall, wo ein POST eintreffen kann, braucht es 307 oder 308.
Die zweite Falle: dauerhafte Weiterleitungen werden gecacht
Diese wird häufiger vergessen als das Methodenproblem.
301 und 308 erklären den Umzug für dauerhaft, und ein Browser darf sie lange zwischenspeichern — mitunter bis der Nutzer seinen Cache leert. Danach wird der Server schlicht nicht mehr gefragt.
Daraus folgt die Regel: ein irrtümlich gesetztes 301 lässt sich kaum zurücknehmen. Sie korrigieren die Konfiguration, aber Besucher, die die alte Antwort bereits erhalten haben, werden weiter umgeleitet. Bei 302 und 307 tritt das nicht auf — sie sind per Definition temporär.
Praktischer Rat: Solange ein Umzugsschema noch nicht steht, verwenden Sie die temporären Codes. Ein 302 später zu einem 301 zu machen ist einfach; der umgekehrte Weg nicht.
Was wählen
Seite ist endgültig umgezogen und nimmt nur GET an → 301. Der klassische Fall: alte Artikel-URL, geänderte Adressstruktur.
Dasselbe, aber der Endpunkt nimmt POST an → 308. Das betrifft APIs, Webhooks und Formulare.
Das Ziel ändert sich vorübergehend, nur GET → 302.
Vorübergehend, und die Methode muss erhalten bleiben → 307.
Nach einem POST den Nutzer auf eine Ergebnisseite schicken → 303. Das ist das Muster POST/Redirect/GET: Es verwandelt die Anfrage absichtlich in ein GET, damit ein Neuladen der Seite das Formular nicht erneut absendet. Hier ist der Methodenwechsel der Zweck, kein Fehler.
Wo das in der Praxis bricht
Eine http→https-Weiterleitung vor einer API. Der häufigste und unangenehmste Fall. Der Client ist auf http:// konfiguriert, der Server antwortet mit 301 auf https://, die Methode geht verloren. Symptom: GET in den Logs auf einer POST-Route. Behoben durch Ersetzen von 301 durch 308.
Host-Kanonisierung. Die Weiterleitung von www auf ohne www (oder umgekehrt) wird meist als 301 eingerichtet. Für Seiten in Ordnung, doch wenn auf demselben Host eine API liegt, gilt exakt dasselbe Problem.
Formularübermittlung. Ein Formular wird an eine Adresse gesendet, die weiterleitet. Der Nutzer sieht, dass „nichts passiert ist", weil die Daten den Handler nie erreicht haben.
Webhooks. Ein externer Dienst sendet ein POST an eine Adresse, die Sie ihm einmal genannt haben. Ist diese Adresse hinter ein 301 gewandert, hören Webhooks stillschweigend auf zu funktionieren, während die Logs des Absenders eine erfolgreiche Antwort auf die Weiterleitung zeigen.
Alle vier teilen eine Signatur: Der Endpunkt ist gesund, aber die Anfrage erreicht ihn nicht in ihrer ursprünglichen Form. Die Fehlersuche läuft deshalb in die falsche Richtung — man sucht den Fehler im Handler, und er steckt in der Webserver-Konfiguration.
Warum Kürzungsdienste 302 verwenden
Ein Kurzlink liefert fast immer ein 302, und das ist eine bewusste Entscheidung, keine Nachlässigkeit.
Der Grund ist die Dauerhaftigkeit, nicht die Methode: Das Ziel eines Kurzlinks kann sich ändern. Ein 301 würde Browsern erlauben, den Sprung dauerhaft zu cachen, und nach einem Zielwechsel landete ein Teil der Besucher weiterhin auf der alten Adresse. Die Methode spielt hier keine Rolle — Kurzlinks werden mit GET-Anfragen aufgerufen.
Der Mechanismus selbst ist gesondert in wie funktionieren Link-Verkürzer beschrieben.
Was die Wahl des Codes nicht ändert
Zwei weit verbreitete Irrtümer.
Linkkraft. Die Wahl zwischen 301 und 302 beeinflusst die Weitergabe von Linkkraft nicht — Google hat das bereits 2016 bestätigt. Die ausführliche Behandlung steht in geben Kurzlinks Linkkraft weiter?.
Die Wahl der kanonischen Adresse. Weiterleitung und rel="canonical" lösen verschiedene Probleme: Die Weiterleitung nimmt eine Adresse aus dem Verkehr, das Canonical lässt beide erreichbar und benennt die primäre. Wann was zum Einsatz kommt, beschreibt der Leitfaden zu Canonical.
Kurze Checkliste
- Auf Routen, die
POSTannehmen, 307 oder 308 verwenden, nicht 302 und 301. - Die http→https-Weiterleitung gesondert prüfen: Sie wird oft pauschal gesetzt, und die API wird vergessen.
- Solange das Schema noch nicht steht, temporäre Codes. 301 und 308 werden gecacht und sind kaum umkehrbar.
- Nach der Formularverarbeitung 303 verwenden — das ist korrektes Verhalten, kein Fehler.
- Ketten auf einen einzigen Sprung reduzieren: jeder zusätzliche Sprung bringt Latenz und Risiko.