Php impedisce il reinvio del modulo. Come posso impedire a un modulo di inviare nuovamente un messaggio? Impedire il reinvio dei moduli utilizzando un reindirizzamento lato client

Un tempo ero perplesso sulla questione di come proteggere le pagine del sito dall'invio ripetuto di dati del modulo durante l'aggiornamento della pagina (se c'era stato un invio prima, ovviamente).
Ogni webmaster e sviluppatore probabilmente sa che se hai fatto clic sul pulsante "invia" su un sito Web compilando un modulo, dopo l'invio, se provi ad aggiornare la pagina, il browser visualizzerà un messaggio di conferma del nuovo invio.
In alcuni casi questo potrebbe essere inaccettabile. Ad esempio, nel caso della forma elementare feedback. Quando l'utente ha compilato il modulo e inviato un messaggio, e poi per qualche motivo noto solo a lui ha aggiornato la pagina, la lettera è stata inviata nuovamente. Questo, ovviamente, potrebbe non essere un caso così fatale, solo per fare un esempio. Tutto è molto più doloroso, ad esempio, quando si invia un ordine in un negozio online.
Quindi mi sono chiesto come trovare una soluzione a questo problema e ho capito che esisteva una sola soluzione: utilizzare un reindirizzamento dopo aver inviato il modulo di intestazione ("posizione: indirizzo"). Quelli. È semplice: dopo l'invio chiamiamo un reindirizzamento (puoi anche andare alla stessa pagina) e il gioco è fatto! L'aggiornamento della pagina sarà pulito, senza POST e GET completati.

Andrebbe tutto bene, ma personalmente ho riscontrato alcuni problemi con questo. Sono i seguenti. In precedenza, senza utilizzare i reindirizzamenti, il meccanismo di invio dei dati sui miei siti funzionava come segue:
L'utente compila il modulo, fa clic su "invia", lo script accetta i dati inviati, ne verifica la correttezza (validità, completamento dei dati richiesti, ecc.) e fornisce una risposta: l'operazione è andata a buon fine oppure si è verificato un errore e un elenco di errori (ad esempio: errore - Il campo "nome" non è compilato. E nella pagina di invio viene visualizzato il messaggio corrispondente: l'invio è riuscito o non è riuscito.
Se l'invio non va a buon fine, il modulo rimane sullo schermo e i suoi campi vengono compilati con i dati inseriti dall'utente. Quelli. i dati vengono presi dalla variabile $_POST (se il metodo è POST) e inseriti negli appositi campi (cioè restituiti dal post ai suoi campi in modo da non inserirli nuovamente). Dopotutto, tutti si arrabbiano quando compili un modulo e Dio non voglia che tu abbia inserito qualcosa in modo errato e quando provi a inviartelo, viene visualizzato un messaggio che qualcosa è stato compilato in modo errato e il modulo viene aggiornato ed è vuoto Ancora. E a causa di un campo compilato in modo errato, devi compilarlo di nuovo.
Quindi, come ho già detto, in caso di mancato completamento, il modulo rimane riempito con i dati presi da $_POST, e l'utente può correggere i dati errati e inviare nuovamente il modulo.
Tutto andava bene e tutto funzionava.
Ma poi l'ho inviato utilizzando il reindirizzamento e si è scoperto che dopo aver fatto clic sul pulsante "invia", se la compilazione non andava a buon fine, il modulo veniva aggiornato e i campi compilati non potevano più rimanere al suo interno, perché In precedenza, venivano compilati automaticamente dall'array $_POST, ma ora, dopo il reindirizzamento, $_POST veniva cancellato come se non fosse avvenuto alcun invio.
Ma anche in questo caso c'era una via d'uscita. Usa le sessioni. Quelli. Prima di chiamare l'intestazione, trasferire i dati dal POST alle variabili di sessione e solo successivamente operare con esso dopo il reindirizzamento.
Di conseguenza, il codice è diventato notevolmente più complicato. Il debug è diventato più complicato perché In generale, è difficile determinare cosa succede alle funzioni nel momento in cui avviene il reindirizzamento. Se hai commesso qualche errore nei codici (che compaiono proprio al momento dell'invio), non verranno nemmeno visualizzati, perché si verificherà un reindirizzamento e non vedrai nemmeno il messaggio di errore.
In generale, dopo aver implementato l'intestazione nei miei codici, è diventato più difficile per me lavorare con le mie applicazioni. Lo sviluppo/perfezionamento/ricerca degli errori è diventato più complicato. Ma non posso rifiutare neanche questo.
E continuo a chiedermi: esistono altre soluzioni più eleganti?

Ricevo spesso domande riguardanti l'annullamento del reinvio dei moduli. Ad esempio, hai creato un modulo per aggiungere un commento e aggiunto un gestore alla stessa pagina. Quindi, quando si aggiunge un commento, questo viene aggiunto con successo, ma non appena l'utente preme F5, il modulo verrà inviato nuovamente. E l'utente può facilmente premere F5 se la pagina impiega molto tempo a caricarsi. Di conseguenza, invece di 1 commento ce ne saranno fino a 2, o anche di più. In questo articolo mostrerò come evitare questo problema.

Innanzitutto, esaminiamo il problema in modo più dettagliato utilizzando questo codice come esempio:









Facendo clic sul pulsante "Quadrato", vedrai il risultato dello script. Ma non appena l'utente preme F5, lo script verrà eseguito nuovamente. In questo caso, questo non è così critico come nel caso dell'aggiunta di un commento, tuttavia, perché è necessario un carico aggiuntivo sul server?

Ora parliamo dei modi per risolvere questo problema. Il primo modo è separare lo script di elaborazione in un file separato. Quindi nell'attributo action del tag form devi aggiungere il percorso a questo script. E lo script stesso deve salvare da qualche parte il risultato delle sue azioni, o le variabili arrivate allo script, e quindi reindirizzarlo nuovamente. In generale, guarda il codice dello script:

E il codice per la pagina con il modulo ora sarà simile a questo:









Lo svantaggio di questo approccio è ovvio: devi creare un altro file per uno script così semplice. Pertanto, ti parlo del secondo metodo, come evitare di inviare nuovamente il modulo:









Anche in questo caso l'elaborazione avviene nello stesso file, ma la differenza fondamentale è la presenza alla fine di un reindirizzamento alla stessa pagina. Di conseguenza, la pagina verrà ricaricata dopo aver inviato il modulo e il browser non chiederà all'utente di inviare nuovamente il modulo quando si preme F5.

Vorrei riassumere come annullare il reinvio di un modulo:

  • Oppure esegui l'elaborazione fascicolo separato, quindi reindirizzare di nuovo da lì.
  • Oppure esegui l'elaborazione nello stesso file del modulo, ma dopo l'elaborazione esegui un reindirizzamento alla stessa pagina.

Ecco come viene fatto in semplici script. E, in quelli complessi, alla fine si fa la stessa cosa.

Diciamo che stiamo creando uno script che accetta dati da un modulo inviato utilizzando il metodo POST. Lo script ha ricevuto i dati, li ha elaborati e ha visualizzato una pagina con il risultato. Ma se l'utente decide di aggiornare la pagina in questo momento, vedrà un messaggio come questo:

Per visualizzare questa pagina, Firefox deve inviare informazioni che ripeteranno qualsiasi azione eseguita in precedenza (ad esempio, una richiesta di ricerca o un acquisto online).

E due pulsanti. Facendo clic su uno di essi verranno inviati nuovamente i dati, il che spesso è indesiderabile. Facendo clic sul secondo non si aggiornerà la pagina. In ogni caso, l'utente non si sente bene con un messaggio del genere. Agli utenti generalmente non piacciono tutti i tipi di finestre pop-up.

Per cominciare, ti mostrerò la sceneggiatura che finiremo.

Puoi inviare il modulo una volta, quindi premere Ctrl+R e vedere la finestra sfortunata. Liberiamocene.

Ma prima, una parola dallo sponsor del post: un sito con contenuti utili per Telefoni Samsung, che offre temi per Samsung GT S5230, sfondi e altro ancora.

Impedire il reinvio del modulo utilizzando il reindirizzamento del server

Per evitare che i dati del modulo vengano inviati nuovamente, puoi eseguire un reindirizzamento del server. Questo viene fatto inviando al browser un'intestazione Location con l'URL desiderato. Ad esempio, questa dovrebbe essere una pagina di ringraziamento per aver completato il modulo. Quindi scriveremo qualcosa del tipo:

In questo caso, il server riceverà i dati, li elaborerà e invece di mostrare il risultato, invierà il client a una pagina in cui verrà mostrato questo risultato.

Lo svantaggio di questo metodo è che l'utente può fare clic sul pulsante Indietro e tornare alla pagina reindirizzata. Lo lancerà di nuovo in avanti e quindi l'utente difficilmente sarà in grado di riportare due pagine al modulo originariamente completato.

Impedire il reinvio dei moduli utilizzando un reindirizzamento lato client

Un reindirizzamento client è denominato reindirizzamento client perché avviene sul lato client. Cioè, nel browser. Il reindirizzamento del client può avvenire utilizzando JavaScript e meta tag.

JavaScript ha il vantaggio di sovrascrivere la cronologia del browser in modo che, anche se l'utente fa clic sul pulsante Indietro del browser, non tornerà alla pagina restituita dal gestore del modulo. Cioè, la finestra scomparirà completamente. Ma alcune persone hanno JS disabilitato.

I META tag, invece, hanno il vantaggio di essere versatili. Reindirizzano tutti, sempre.

Sarebbe ottimale combinare questi due metodi. Come - descritto da Alexander Shurkayev in una nota reindirizzamento ottimale.

Usiamo il suo metodo come segue.

Proviamo! Ora, come puoi vedere, non appare alcuna finestra. Cosa abbiamo fatto? Abbiamo controllato. Se i dati sono stati ricevuti, visualizziamo tutto il necessario per il reindirizzamento. In linea di principio, dopodiché puoi anche uscire, per non caricare il browser con dati non necessari che comunque nessuno vedrà.