307 en 308 redirect: doorsturen met behoud van methode

Het verschil tussen 307, 308, 301 en 302: waarom formulieren en API-calls een redirect nodig hebben die de HTTP-methode behoudt.

De meeste mensen kennen alleen de 301 en de 302. Toch zijn er nog twee redirects die je af en toe nodig hebt: de 307 en de 308. Ze doen hetzelfde als hun bekendere broers, met één belangrijk verschil. Een formulier of API-verzoek dat met POST wordt verstuurd, blijft ook na de redirect een POST.

Het probleem met 301 en 302

Een browser kan op verschillende manieren een verzoek doen. Met GET haal je een pagina op. Met POST stuur je gegevens mee, bijvoorbeeld de inhoud van een contactformulier of een bestelling.

Krijgt een browser op een POST-verzoek een 301 of 302 terug, dan maken de meeste browsers van het vervolgverzoek een GET. De gegevens die je verstuurde, gaan dan verloren. Dat gedrag stond oorspronkelijk niet zo in de standaard, maar browsers deden het massaal en de standaard heeft het later toegestaan.

Voor een gewone webpagina merk je daar niets van. Voor een formulier dat naar een nieuw adres is verhuisd, of een API-endpoint dat een andere URL krijgt, gaat het wel mis: de server krijgt een leeg verzoek binnen.

Wat doen 307 en 308?

Bij een 307 of 308 moet de browser het vervolgverzoek met dezelfde methode doen. Een POST blijft een POST, en de body wordt opnieuw meegestuurd naar het nieuwe adres. Een PUT blijft een PUT, een DELETE blijft een DELETE.

  • 307 Temporary Redirect is de tijdelijke variant, de strikte versie van een 302.
  • 308 Permanent Redirect is de permanente variant, de strikte versie van een 301.

Alle redirects naast elkaar

CodeNaamPermanent?Mag de methode veranderen?
301Moved PermanentlyJaJa, POST wordt in de praktijk GET
302FoundNeeJa, POST wordt in de praktijk GET
303See OtherNeeAltijd GET
307Temporary RedirectNeeNee
308Permanent RedirectJaNee

De 303 valt een beetje buiten de rij. Die gebruik je bewust om na een POST door te sturen naar een gewone pagina, zoals een bedankpagina. Zo voorkom je dat een bezoeker het formulier opnieuw verstuurt als hij de pagina ververst.

Waar komen 307 en 308 vandaan?

De 303 en 307 kwamen er bij HTTP/1.1, juist om de onduidelijkheid rond 302 op te lossen. De 308 kwam later: die werd vastgelegd in RFC 7538, als permanente tegenhanger van de 307. De andere codes waren toen beschreven in RFC 7231.

Tegenwoordig staan alle redirect-codes, inclusief 308, samen in RFC 9110, de huidige beschrijving van HTTP-semantiek. Die vervangt de oudere documenten. Voor jou verandert er inhoudelijk niets: de betekenis van de codes is gelijk gebleven.

Wanneer gebruik je ze?

Formulieren

Verhuist een pagina met een formulier naar een nieuw adres, en kunnen er nog formulieren of oude pagina’s naar het oude adres posten? Dan zorgt een 308 dat de ingevulde gegevens aankomen. Met een 301 zou de server alleen een lege GET zien.

API’s

Een API die verhuist naar een nieuw domein of pad, krijgt van allerlei clients nog verzoeken op het oude adres. Met een 308 komen POST-, PUT- en DELETE-verzoeken met hun body op de nieuwe plek aan. Let wel op: niet elke HTTP-client volgt redirects automatisch, en sommige stoppen bij een redirect naar een ander domein. Laat clients dus ook zelf hun URL bijwerken.

Webhooks

Diensten die webhooks sturen, doen dat bijna altijd met POST. Verandert het adres van je webhook-ontvanger, dan is een 307 of 308 de enige redirect die de payload behoudt. Of de afzender redirects volgt, verschilt per dienst. Het veiligste blijft de webhook-URL bij de afzender aan te passen en de redirect als vangnet te gebruiken.

Tijdelijk omleiden van een endpoint

Is een server tijdelijk in onderhoud en wil je verzoeken naar een andere server sturen, dan is een 307 de juiste keuze. De methode blijft gelijk en clients blijven het oude adres gebruiken zodra het weer beschikbaar is.

Instellen op je eigen server

In nginx werkt het net als een 301, alleen met een andere code:

location /api/ {
    return 308 https://api.voorbeeld.nl$request_uri;
}

In Apache met mod_rewrite geef je de code mee aan de R-vlag:

RewriteEngine On
RewriteRule ^api/(.*)$ https://api.voorbeeld.nl/$1 [R=308,L]

Test daarna met een echt POST-verzoek, want een GET laat het verschil niet zien. Met curl volg je de redirect met -L, en zorgt --post301 of --post302 ervoor dat curl ook bij een 301 of 302 de POST behoudt. Bij een 307 of 308 is dat niet nodig:

curl -i -L -X POST -d "naam=test" http://voorbeeld.nl/api/aanmelden

De 307 die je in DevTools ziet

Open je de netwerktab van je browser en typ je http:// voor een domein, dan zie je soms een 307 met de tekst "Internal Redirect" of "Non-Authoritative Reason: HSTS". Die komt niet van de server.

Het domein gebruikt dan HSTS (HTTP Strict Transport Security). Daarmee heeft de website eerder aan je browser gezegd: benader mij alleen via https. Je browser onthoudt dat en zet een http-adres meteen zelf om naar https, nog voordat er een verzoek de deur uit gaat. In DevTools wordt dat weergegeven als een 307, omdat de methode gelijk blijft.

Belangrijk om te weten bij het testen: je browser laat je dan niet zien wat de server zelf op http antwoordt. Gebruik daarvoor de redirect checker of curl, die geen HSTS-geheugen hebben.

curl -I http://voorbeeld.nl

307 en 308 voor SEO

Voor Google is de keuze simpel. Een 308 wordt behandeld als een 301: een permanente verhuizing, waarbij de nieuwe URL in de index komt. Een 307 wordt behandeld als een 302: tijdelijk, de oude URL blijft de canonieke.

Voor een domeinverhuizing of een gewone pagina kun je dus zonder bezwaar een 301 blijven gebruiken. Lees meer in de gids over de 301 redirect en de 302 redirect.

In WebsiteRedirect

Bij elke redirect kies je zelf de statuscode: 301, 302, 307 of 308. Stuur je een domein door waar ook formulieren of API-verzoeken op binnenkomen, kies dan 308 voor een blijvende verhuizing of 307 voor een tijdelijke.

Veelgestelde vragen

Is een 308 hetzelfde als een 301?

Bijna. Beide zijn permanente redirects en Google behandelt ze op dezelfde manier. Het verschil is dat een 308 de HTTP-methode en de verstuurde gegevens behoudt. Bij een 301 mag een browser een POST omzetten in een GET.

Waarom zie ik een 307 Internal Redirect in mijn browser?

Dat is meestal HSTS. Je browser weet dat het domein alleen via https bereikbaar is en stuurt een http-verzoek zelf door naar https, nog voordat er iets naar de server gaat. De server heeft die 307 dus niet verstuurd.

Moet ik voor een gewone website 308 gebruiken in plaats van 301?

Dat hoeft niet. Voor pagina’s die bezoekers gewoon openen, werken 301 en 308 hetzelfde. Een 308 is vooral nuttig als er ook formulieren of API-verzoeken via dezelfde URL lopen.

Ondersteunen alle browsers 307 en 308?

Alle gangbare browsers ondersteunen 307 en 308 al jaren. Alleen heel oude software of eenvoudige scripts kunnen er nog moeite mee hebben.

Redirects regelen zonder gedoe?

Onbeperkt domeinen, elke statuscode, automatisch SSL. Vast €10 per maand.