303 See Other: il redirect dopo un POST di modulo
303 See Other dice al client che la richiesta è stata gestita e che il risultato si trova a un URL diverso, che dovrebbe recuperare con GET. È la risposta corretta a un invio di modulo che dovrebbe far atterrare il visitatore su una pagina di risultato o di conferma invece di lasciarlo sul POST.
A cosa serve 303
Un 303 in realtà non riguarda lo spostamento di una risorsa. Riguarda la separazione di un'azione dal suo risultato. Il client invia un POST, il server esegue l'azione, e poi invece di restituire il risultato nella risposta al POST risponde con 303 e un'intestazione Location. Il client fa un nuovo GET verso quella posizione, e la barra degli indirizzi del browser finisce su un URL ordinario che si può aggiungere ai preferiti e ricaricare.
La regola che lo definisce è il metodo: qualunque fosse il metodo della richiesta originale, la richiesta successiva verso l'URL Location è un GET. È l'opposto di 307 e 308, che richiedono che il metodo e il corpo originali vengano preservati.
Post/Redirect/Get, e il problema che risolve
Senza un redirect dopo un POST, la pagina di risultato appartiene alla richiesta POST, il che causa problemi noti:
- Premere ricarica reinvia il modulo, così l'ordine viene effettuato o il commento pubblicato due volte. I browser avvisano di questo con un dialogo "conferma reinvio modulo", che è già di per sé un'esperienza scadente.
- La pagina non può essere salvata nei preferiti né condivisa, perché l'URL non descrive il contenuto.
- Il pulsante indietro atterra su un avviso di reinvio invece che sulla pagina precedente.
Post/Redirect/Get li risolve tutti e tre. Il POST esegue l'azione e risponde 303; il browser fa un GET sull'URL di risultato; un ricaricamento ora recupera solo di nuovo una pagina innocua. Ecco perché quasi ogni framework ha un aiuto "redirect dopo il salvataggio".
303 contro 302 contro 307
- 302 Found è un redirect temporaneo la cui gestione del metodo è storicamente ambigua. La maggior parte dei client trasforma un POST in un GET quando lo segue, il che di solito è quello che si voleva, ma lo standard non lo richiede. Molti framework emettono ancora 302 per post-poi-redirect e funziona nella pratica.
- 303 See Other rende questo comportamento esplicito e obbligatorio. Se la tua intenzione è "non ripetere il mio POST, vai a fare un GET su questo invece", 303 lo dichiara senza ambiguità.
- 307 Temporary Redirect è quello da evitare qui. Richiede che il POST venga ripetuto verso il nuovo URL, il che per un invio di modulo significa eseguire l'azione due volte.
Un avvertimento pratico: 303 è stato introdotto con HTTP/1.1, quindi un client che parla HTTP/1.0 potrebbe non comprenderlo. Alcuni framework per questo usano 302 come predefinito. Sul web moderno è raramente un vincolo reale, ma spiega la divisione di comportamenti predefiniti che vedrai tra i vari linguaggi.
Dove compare 303 in altri casi
- API che avviano lavori di lunga durata. Un POST avvia un job e risponde 303 con l'URL di stato di quel job, oppure 202 con un URL di stato nel corpo. Entrambi i modelli sono in uso; 303 ha il vantaggio che un browser lo segue automaticamente.
- Flussi OAuth e di accesso. Alcuni server di autorizzazione reindirizzano all'applicazione client con un 303 così il callback viene recuperato con GET indipendentemente da come è arrivata la richiesta.
- Configurazioni linked-data e content-negotiation, che distinguono una cosa reale dal documento che la descrive, e usano 303 per inviare i client dall'identificatore al documento.
Come usarlo e verificarlo
- Dopo un POST riuscito, restituisci 303 con una
Locationassoluta che punta alla pagina di risultato. Non renderizzare il risultato in linea. - Rendi la destinazione idempotente. Verrà recuperata di nuovo a ogni ricaricamento e a ogni navigazione indietro, quindi deve essere sicura da recuperare ripetutamente con GET.
- Porta ogni messaggio una tantum, come "le tue modifiche sono state salvate", nello stato di sessione o in un parametro di query invece che nel corpo del redirect. Il corpo di una risposta 303 normalmente non viene mostrato.
- Verifica il codice e la destinazione:
Dovresti vederecurl -si -X POST -d "name=test" https://example.com/submit | grep -Ei "^(HTTP|location)"HTTP/1.1 303 See Othere l'URL di risultato. - Seguila e conferma che la seconda richiesta sia un GET che restituisce 200. Se vedi un POST ripetuto nei log del tuo server, la regola è un 307 e va cambiata.
- Controlla che la destinazione non sia essa stessa un redirect. Un 303 dentro un 301 dentro la pagina reale sono tre round trip per un solo invio di modulo.
Monitorare gli endpoint dietro un modulo
Un flusso post-poi-redirect rotto è invisibile a un controllo che recupera solo la homepage. Il sito è raggiungibile, il modulo si visualizza, e solo chi lo invia incontra il fallimento. Intercettalo presto monitorando gli endpoint dietro l'azione, come la pagina di risultato, l'URL di conferma e la rotta di stato del job, e verificando il codice di stato e il contenuto attesi su ciascuno. HostTracker offre 13 tipi di monitor e avvisa via email, SMS, chiamata vocale, Slack, Telegram e altro. Verifica cosa restituisce un URL qualsiasi con lo strumento di controllo HTTP, e leggi 301 contro 302 e la guida completa alla famiglia di redirect 3xx per i codici vicini.