2009-03-18 6 views
37

Ho un'applicazione che fornisce un lungo elenco di parametri a una pagina Web, quindi devo usare POST anziché GET. Il problema è che quando la pagina viene visualizzata e l'utente fa clic sul pulsante Indietro, Firefox si presenta un avvertimento:Previene il pulsante Indietro per visualizzare l'avviso di conferma POST

Per visualizzare questa pagina, Firefox deve inviare informazioni che si ripeterà ogni azione (come ad esempio una conferma di ricerca o di ordine) è stato eseguito prima.

Poiché l'applicazione è costruita in modo tale che tornare indietro è un'operazione abbastanza comune, questo è davvero fastidioso per gli utenti finali.

In sostanza, vorrei farlo nel modo questa pagina fa:

http://www.pikanya.net/testcache/

Inserisci qualcosa, presentare, e fare clic su Indietro pulsante. Nessun avvertimento, torna indietro.

Googling Ho scoperto che questo potrebbe essere un bug in Firefox 3, ma mi piacerebbe in qualche modo ottenere questo comportamento anche dopo averlo "corretto".

Immagino che potrebbe essere possibile con alcune intestazioni HTTP, ma quale?

+0

Proprio così mi assicuro che so che cosa sta succedendo qui, si può incollare il testo della segnalazione? –

+0

La pagina collegata non elimina l'avviso. Vedo ancora: Conferma Per visualizzare questa pagina, Firefox deve inviare informazioni che ripeteranno qualsiasi azione (come una ricerca o conferma d'ordine) che è stata eseguita in precedenza. [Invia nuovamente] [Annulla] – Sparr

+0

Non se si utilizza Firefox 3.0.6 o una versione simile. Probabilmente hai un browser in cui è stato "corretto". –

risposta

27

Un modo per reindirizzare il POST a una pagina che reindirizza a un GET - vedere Post/Redirect/Get on wikipedia.

Supponiamo che il tuo POST sia 4K di dati del modulo. Presumibilmente il tuo server fa qualcosa con quei dati piuttosto che visualizzarli una sola volta e gettarli via, ad esempio salvarli in un database. Continuate a farlo, o se è un enorme modulo di ricerca, creane una copia temporanea in un database che viene eliminato dopo pochi giorni o su base LRU quando viene utilizzato un limite di spazio. Ora creare una rappresentazione dei dati a cui è possibile accedere tramite GET. Se è temporaneo, genera un ID per esso e lo usa come URL; se è un insieme permanente di dati, probabilmente ha un ID o qualcosa che può essere usato per l'URL. Nel peggiore dei casi, un algoritmo come il piccolo url utilizzato può comprimere un grosso URL in uno molto più piccolo. Reindirizzare il POST per ottenere la rappresentazione dei dati.


Come nota storica, questa tecnica era established practice in 1995.

+1

Ma come? I dati di input sono superiori a 4kB e l'output della pagina dipende da questo. –

+0

Sembra che dovrò farlo in questo modo, a meno che non ci sia qualche trucco con la cache. –

+1

non usare trucchi e fallo esattamente come suggeriva Pete. quello che mi piace della sua soluzione è che segue semplici principi REST. –

3

Un modo per evitare tale avviso/comportamento è eseguire il POST tramite AJAX, quindi inviare l'utente a un'altra pagina (o meno) separatamente.

+1

Sì, questo è il mio piano di backup. Ma, il pulsante BACK non funziona con AJAX, quindi dovrò implementare il mio "back handler" in questo caso, che voglio evitare. –

37

Vedi il mio regola d'oro di programmazione web qui:

Stop data inserting into a database twice

Dice: “Mai e poi mai rispondere con un corpo a un POST-richiesta. Esegui sempre il lavoro, quindi rispondi con un'intestazione Location: per reindirizzare alla pagina aggiornata in modo che il browser lo richieda con GET "

Se il browser chiede sempre all'utente di re-POST, l'app Web è interrotta. L'utente non dovrebbe mai vedere questa domanda.

+0

Per produrre la pagina web ho bisogno di fornire circa 4k di input. Non posso farlo con GET. Non c'è "lavoro" da fare, l'output stesso dipende dai parametri dati.L'unico pensiero che posso pensare è di memorizzare quel 4k di dati nella sessione PHP e recuperarlo nella richiesta GET, ma se l'utente ha ... –

+0

... le schede aperte della mia applicazione, non funzionerebbe. –

+8

Sembra Amazon non seguire questa regola d'oro –

1

Ho un'applicazione che fornisce un lungo elenco di parametri a una pagina Web, quindi devo usare POST anziché GET.Il problema è che quando viene visualizzata la pagina e l'utente fa clic sul pulsante Indietro, Firefox mostra un avviso:

Il tuo ragionamento è sbagliato. Se la richiesta è senza effetti collaterali, dovrebbe essere GET. Se ha effetti collaterali, dovrebbe essere POST. La scelta non dovrebbe essere basata sul numero di parametri che è necessario passare.

+3

Non ci sono effetti collaterali, ma i parametri sono 4kB. Nel caso in cui non lo sapessi, GET ha un limite di 1024 byte. –

+0

Che tipo di parametri occupa tutto questo spazio? Puoi forse spiegare un po 'più il contesto della tua applicazione? – troelskn

+0

Fingere è una ricerca di immagini inversa, in cui i dati del post sono un'immagine. –

2

Ho usato la variabile Session per aiutare in questa situazione. Ecco il metodo che uso che ha lavorato molto per me per anni:

//If there's something in the POST, move it to the session and then redirect right back to where we are 
if ($_POST) { 
    $_SESSION['POST']=$_POST; 
    redirect($_SERVER["REQUEST_URI"]); 
} 

//If there's something in the SESSION POST, move it back to the POST and clear the SESSION POST 
if ($_SESSION['POST']) { 
    $_POST=$_SESSION['POST']; 
    unset($_SESSION['POST']); 
} 

Tecnicamente non è nemmeno bisogno di mettere di nuovo in una variabile chiamata $ _POST. Ma mi aiuta a tenere traccia di quali dati sono arrivati ​​da dove.

0

Come un'altra soluzione potresti smettere di utilizzare il reindirizzamento.

È possibile elaborare e visualizzare il risultato di elaborazione in una volta senza avviso di conferma POST. Si dovrebbe solo manipolare l'oggetto cronologia del browser:

history.replaceState("", "", "/the/result/page") 

Vedi full o short risponde