Přejít na hlavní obsah

Návody / HTTP stavové kódy vysvětlené

303 See Other: přesměrování po POST formuláře

303 See Other říká klientovi, že požadavek byl zpracován a výsledek je na jiné URL adrese, kterou by měl stáhnout metodou GET. Je to správná odpověď na odeslání formuláře, které má návštěvníka dostat na výslednou nebo potvrzovací stránku, místo aby ho nechalo stát na POST.

K čemu 303 slouží

303 se ve skutečnosti netýká přesunu zdroje. Jde o oddělení akce od jejího výsledku. Klient odešle POST, server akci provede, a místo aby výsledek vrátil přímo v odpovědi na POST, odpoví 303 a hlavičkou Location. Klient provede nový GET na danou adresu, a adresní řádek prohlížeče nakonec skončí na obyčejné URL adrese, kterou lze uložit do záložek a znovu načíst.

Určujícím pravidlem je metoda: bez ohledu na to, jaká byla metoda původního požadavku, navazující požadavek na URL adresu z Location je vždy GET. To je opak 307 a 308, které vyžadují zachování původní metody i těla požadavku.

Post/Redirect/Get a problém, který to řeší

Bez přesměrování po POST patří výsledná stránka požadavku POST, což způsobuje známé problémy:

  • Stisknutí obnovit znovu odešle formulář, takže se objednávka zadá nebo komentář publikuje dvakrát. Prohlížeče na to upozorňují dialogem "potvrdit opětovné odeslání formuláře", což samo o sobě není dobrý zážitek.
  • Stránku nelze uložit do záložek ani sdílet, protože URL adresa nepopisuje obsah.
  • Tlačítko zpět skončí na výzvě k opětovnému odeslání místo na předchozí stránce.

Post/Redirect/Get vyřeší všechny tyto problémy najednou. POST provede akci a odpoví 303; prohlížeč provede GET na výslednou URL adresu; obnovení stránky teď jen znovu stáhne neškodnou stránku. Proto má téměř každý framework pomocnou funkci "přesměrovat po uložení".

303 vs 302 vs 307

  • 302 Found je dočasné přesměrování, jehož zacházení s metodou je historicky nejednoznačné. Většina klientů při následování změní POST na GET, což bývá obvykle to, co jste chtěli, ale standard to nevyžaduje. Řada frameworků stále vrací 302 pro vzor post-then-redirect a v praxi to funguje.
  • 303 See Other dělá toto chování explicitním a povinným. Pokud je váš záměr "neopakuj můj POST, jdi a stáhni si tohle metodou GET", 303 to vyjádří jednoznačně.
  • 307 Temporary Redirect je ten, kterému je tu potřeba se vyhnout. Vyžaduje zopakování POST na novou URL adresu, což u odeslání formuláře znamená provedení akce dvakrát.

Jedna praktická výhrada: 303 byl zaveden v HTTP/1.1, takže klient mluvící HTTP/1.0 mu nemusí rozumět. Některé frameworky proto ve výchozím stavu používají 302. V dnešním webu to bývá jen zřídka reálné omezení, ale vysvětluje to rozdílné výchozí chování mezi jazyky.

Kde jinde se 303 objevuje

  • API, která spouští dlouho běžící práci. POST spustí úlohu a odpoví 303 se stavovou URL adresou dané úlohy, nebo 202 se stavovou URL adresou v těle. Používají se oba vzory; 303 má tu výhodu, že ho prohlížeč následuje automaticky.
  • OAuth a přihlašovací toky. Některé autorizační servery přesměrují zpět na klientskou aplikaci pomocí 303, aby se callback stáhl metodou GET bez ohledu na to, jak požadavek dorazil.
  • Nastavení propojených dat a vyjednávání obsahu (content negotiation), která rozlišují skutečnou věc od dokumentu, jenž ji popisuje, a používají 303 k přesměrování klientů z identifikátoru na dokument.

Jak to používat a ověřit

  1. Po úspěšném POST vraťte 303 s absolutní hlavičkou Location ukazující na výslednou stránku. Výsledek nevykreslujte přímo v odpovědi.
  2. Cíl udělejte idempotentní. Bude stahován znovu při každém obnovení stránky i navigaci zpět, takže musí být bezpečné ho opakovaně stahovat metodou GET.
  3. Jakoukoli jednorázovou zprávu, například "vaše změny byly uloženy", přenášejte přes stav relace nebo parametr dotazu, ne v těle přesměrování. Tělo odpovědi 303 se běžně nezobrazuje.
  4. Ověřte kód i cíl:
    curl -si -X POST -d "name=test" https://example.com/submit | grep -Ei "^(HTTP|location)"
    Měli byste vidět HTTP/1.1 303 See Other a výslednou URL adresu.
  5. Následujte ji a ověřte, že druhý požadavek je GET vracející 200. Pokud v logách serveru vidíte opakovaný POST, pravidlo je ve skutečnosti 307 a je potřeba ho změnit.
  6. Zkontrolujte, že cíl sám není dalším přesměrováním. 303 vedoucí do 301 a teprve pak na skutečnou stránku znamená tři cesty tam a zpět kvůli jednomu odeslání formuláře.

Monitorování endpointů za formulářem

Rozbitý tok post-then-redirect je pro kontrolu, která stahuje jen domovskou stránku, neviditelný. Web běží, formulář se vykreslí a selhání zasáhne jen ty, kdo ho skutečně odešlou. Zachyťte to včas sledováním endpointů za danou akcí, jako je výsledná stránka, potvrzovací URL adresa a trasa stavu úlohy, a u každé z nich ověřujte očekávaný stavový kód i obsah. HostTracker nabízí 13 typů monitorů a upozorňuje e-mailem, SMS, hlasovým hovorem, přes Slack, Telegram a další. Zkontrolujte, co kterákoli URL adresa vrací, pomocí nástroje pro HTTP kontrolu, a přečtěte si 301 vs 302 a celý návod k rodině přesměrování 3xx pro sousední kódy.

Zkontrolovat hned

Spusťte bezplatnou kontrolu na svém webu - bez registrace.

HTTP check

Sledovat trvale

Dostanete upozornění ve chvíli, kdy něco přestane fungovat: HostTracker kontroluje z více než 300 lokalit a upozorní vás e-mailem, SMS, přes Slack, Telegram a další.

Funkce HostTracker

Více v této sekci: HTTP stavové kódy vysvětlené