Naar hoofdinhoud springen

Handleidingen / HTTP-statuscodes uitgelegd

303 See Other: de redirect na een formulier-POST

303 See Other vertelt de client dat het verzoek is verwerkt en dat het resultaat op een andere URL staat, die hij met GET moet ophalen. Het is het juiste antwoord op een formulierinzending die de bezoeker op een resultaat- of bevestigingspagina moet laten landen in plaats van hem op de POST te laten staan.

Waar 303 voor dient

Een 303 gaat niet echt over een resource verplaatsen. Het gaat over een actie scheiden van het resultaat ervan. De client stuurt een POST, de server voert de actie uit, en in plaats van het resultaat in het POST-antwoord terug te geven, antwoordt hij met 303 en een header Location. De client doet een nieuwe GET naar die locatie, en de adresbalk van de browser komt uit op een gewone URL die gebookmarkt en herladen kan worden.

De bepalende regel is de methode: wat de oorspronkelijke verzoekmethode ook was, het vervolgverzoek naar de URL in Location is een GET. Dat is het tegenovergestelde van 307 en 308, die vereisen dat de oorspronkelijke methode en body behouden blijven.

Post/Redirect/Get, en het probleem dat het oplost

Zonder een redirect na een POST hoort de resultaatpagina bij het POST-verzoek, wat bekende problemen veroorzaakt:

  • Op herladen drukken dient het formulier opnieuw in, zodat de bestelling of de reactie twee keer wordt geplaatst. Browsers waarschuwen hiervoor met een dialoogvenster "formulier opnieuw indienen bevestigen", wat op zich al een matige ervaring is.
  • De pagina kan niet worden gebookmarkt of gedeeld, omdat de URL de inhoud niet beschrijft.
  • De terugknop komt uit op een heraanbiedingsprompt in plaats van de vorige pagina.

Post/Redirect/Get lost ze allemaal op. De POST voert de actie uit en antwoordt met 303; de browser haalt de resultaat-URL op met GET; een herlaadactie haalt nu gewoon een onschadelijke pagina opnieuw op. Daarom heeft bijna elk framework een helper "redirect after save".

303 versus 302 versus 307

  • 302 Found is een tijdelijke redirect waarvan de methodeafhandeling historisch dubbelzinnig is. De meeste clients maken van een POST een GET wanneer ze hem volgen, wat meestal is wat u wilde, maar de standaard vereist het niet. Veel frameworks geven nog steeds 302 uit voor post-dan-redirect, en het werkt in de praktijk.
  • 303 See Other maakt dat gedrag expliciet en verplicht. Is uw bedoeling "herhaal mijn POST niet, ga in plaats daarvan dit met GET ophalen", dan zegt 303 dat ondubbelzinnig.
  • 307 Temporary Redirect is hier de te vermijden optie. Het vereist dat de POST tegen de nieuwe URL wordt herhaald, wat voor een formulierinzending betekent dat de actie twee keer wordt uitgevoerd.

Eén praktische kanttekening: 303 werd geïntroduceerd in HTTP/1.1, dus een client die HTTP/1.0 spreekt, begrijpt hem misschien niet. Sommige frameworks kiezen daarom standaard voor 302. Op het moderne web is dat zelden een echte beperking, maar het verklaart de verdeling in standaardwaarden die u tussen talen ziet.

Waar 303 verder nog verschijnt

  • API's die langlopend werk starten. Een POST start een job en antwoordt met 303 en de statusURL van die job, of met 202 en een statusURL in de body. Beide patronen zijn in gebruik; 303 heeft het voordeel dat een browser het automatisch volgt.
  • OAuth- en inlogflows. Sommige autorisatieservers redirecten terug naar de clienttoepassing met een 303, zodat de callback met GET wordt opgehaald ongeacht hoe het verzoek binnenkwam.
  • Linked-data- en content-onderhandelingsopstellingen die een werkelijk ding onderscheiden van het document dat het beschrijft, en 303 gebruiken om clients van de identifier naar het document te sturen.

Hoe u het gebruikt en verifieert

  1. Geef na een geslaagde POST 303 terug met een absolute Location die naar de resultaatpagina wijst. Render het resultaat niet inline.
  2. Maak het doel idempotent. Het wordt bij elke herlaadactie en elke terugnavigatie opnieuw opgehaald, dus moet het veilig zijn om herhaaldelijk met GET op te halen.
  3. Draag elke eenmalige melding, zoals "uw wijzigingen zijn opgeslagen", in sessiestatus of een queryparameter in plaats van in de redirectbody. Een 303-responsbody wordt normaal niet getoond.
  4. Verifieer de code en het doel:
    curl -si -X POST -d "name=test" https://example.com/submit | grep -Ei "^(HTTP|location)"
    U zou HTTP/1.1 303 See Other moeten zien, plus de resultaat-URL.
  5. Volg hem en bevestig dat het tweede verzoek een GET is die 200 teruggeeft. Ziet u een herhaalde POST in uw serverlogs, dan is de regel een 307 en moet ze worden gewijzigd.
  6. Controleer dat het doel zelf geen redirect is. Een 303 naar een 301 naar de echte pagina is drie omwegen voor één formulierinzending.

De endpoints achter een formulier bewaken

Een kapotte post-dan-redirect-flow is onzichtbaar voor een controle die alleen de homepage ophaalt. De site is online, het formulier rendert, en alleen de mensen die het indienen, stuiten op de storing. Betrap het vroeg door de endpoints achter de actie te bewaken, zoals de resultaatpagina, de bevestigings-URL en de jobstatusroute, en op elk de verwachte statuscode en inhoud te controleren. HostTracker biedt 13 monitortypen en waarschuwt via e-mail, sms, spraakoproep, Slack, Telegram en meer. Controleer wat een willekeurige URL teruggeeft met de HTTP-controletool, en lees 301 versus 302 en de volledige handleiding 3xx-doorverwijzingsfamilie voor de naburige codes.

Nu controleren

Voer de gratis check uit op je eigen site, zonder account.

HTTP check

Dit permanent monitoren

Ontvang een melding zodra er iets misgaat: HostTracker controleert vanaf meer dan 300 locaties en waarschuwt je via e-mail, sms, Slack, Telegram en meer.

HostTracker-functies

Meer in dit onderdeel: HTTP-statuscodes uitgelegd