2013-03-05 23 views
17

Ho cercato molti post qui e altrove ma non riesco a trovare una soluzione al mio problema. Ho una pagina che mostra le voci del database: database.php. Queste voci possono essere filtrate con un modulo. Quando li filtro e visualizzo solo quelli a cui sono interessato posso fare clic su una voce (come collegamento) che mi porta a quella pagina di voci (tramite php GET). Quando sono su quella pagina di voci (ad esempio, "view.php? Id = 1") e premo il pulsante Indietro (torna a database.php), il modulo filtro richiede di confermare il nuovo invio del modulo. C'è un modo per prevenire questo?Prevent Modulo di nuovo invio premendo il pulsante Indietro

qui sono alcuni (semplificate) esempi di codice:

database.php:

<form> 
    <select> 
     <option>1</option> 
     <option>2 
     <option> 
    </select> 
    <input type="submit" name="apply_filter" /> 
</form> 
<?php 
if (isset($_POST[ "apply_filter" ])) { // display filtered entries 
    $filter = $_POST[ "filter" ]; 
    $q = "Select * from table where col = '" . $filter . "'"; 
    $r = mysql_query($q); 
} else { // display all entries 
    $q = "Select * from table"; 
    $r = mysql_query($q); 
} 
while ($rec = mysql_fetch_assoc($r)) { 
    echo "<a href='view.php?id=" . $rec[ "id" ] . "'>" . $rec[ "name" ] . "</a><br />"; // this is where the link to the view.php page is... 
} 
?> 

Ora come detto, se clicco sul link, mi prende a "view.php? id = qualunque". In quella pagina, ottengo solo l'ID dall'URL per visualizzare tale singola voce:

view.php:

<?php 
$id = $_GET[ "id" ]; 
$q = "Select * from table where id = '" . $id . "'"; 
$r = mysql_query($q); 
while () { 
    // display entry 
} 

?> 

Se ora mi ha colpito il tasto posteriore, il modulo a database.php (quello usato per filtrare i risultati del DB) richiede la conferma per il nuovo invio. Non solo è molto fastidioso, è anche inutile per me.

Come posso risolvere questo problema? Spero che gli esempi di codice e la spiegazione del mio problema siano sufficienti. Se no fammelo sapere e proverò a specificare.

+3

** ** POST -> * ServerSide 302 Redirect * -> ** ** GET – scunliffe

+0

sono consapevole ci sono un sacco di messaggi con questo argomento. Navigando attraverso di loro non riuscivo a capire il mio problema, quindi ho deciso di chiederlo come una nuova domanda. – user1889382

+0

Probabilmente vuoi usare il pattern 'Post-Redirect-Get', vedi https://en.wikipedia.org/wiki/Post/Redirect/Get e anche http://stackoverflow.com/questions/15288229/automatically- rinvia-post-richiesta-nel-browser-quando-navigando-usando-back-tasto –

risposta

9

Ci sono due modi in cui so di farlo. Il modo semplice e il modo difficile.

Indipendentemente dal modo in cui, quando si tratta di una pagina basata sullo stato (utilizzando $_SESSION), che si dovrebbe fare per mantenere le vostre pagine "dal vivo" e sotto il vostro controllo, è impedire la memorizzazione nella cache di tutte le pagine come questo :

<?php 
//Set no caching 
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
header("Cache-Control: no-store, no-cache, must-revalidate"); 
header("Cache-Control: post-check=0, pre-check=0", false); 
header("Pragma: no-cache"); 
?> 

il modo difficile consiste nel generare un id e riporlo da qualche parte sulla pagina come input nascosto o un biscotto &_SESSION. Quindi memorizzi lo stesso id sul server come $_SESSION. Se non corrispondono, una serie di istruzioni di tipo ifelse preprogrammate non causerà alcun problema con la pagina viene nuovamente inviata (che è ciò che tenta di fare quando si fa clic indietro).

Il modo più semplice è quello di reindirizzare semplicemente l'utente alla pagina di presentazione modulo se il modulo è stato inviato con successo, in questo modo:

header('Location: http://www.mydomain.com/redirect.php'); 

Spero che questo aiuta!

+1

Non sto capendo il "modo semplice" .. se l'utente è sulla pagina "view" non c'è modo di reindirarlo poiché non so per quanto tempo vuole guardare le informazioni su quella pagina. Ho incluso un pulsante di reindirizzamento che riporta l'utente alla pagina del modulo; questo non è un problema. Solo se l'utente preme indietro per tornare all'intero DB il problema si presenta. – user1889382

+0

Dovresti inviare dal tuo modulo a 'Database.php', raccogliere tutte le informazioni e reindirizzare l'utente alla fine di quello script usando l'URL di stile' $ _GET' nell'intestazione '(Location: http: // www.mydomain.com/view.php?databse=this&somethingelse=that '); ' –

3

Una cosa che potrebbe aiutare è rendere il modulo filtro utilizza un metodo GET anziché POST.

I browser di solito impediscono l'invio di POST input, che è qualcosa che non fanno quando viene utilizzato l'input GET. Inoltre, questo permetterà agli utenti di collegarsi alla tua pagina usando un filtro.

+1

Questa soluzione è ideale per moduli di ricerca/filtro. Per creare/aggiornare il reindirizzamento del modulo è il migliore. –

17

So che questa domanda è vecchio, ma avendo questo problema io stesso, due righe ho scoperto che le opere sono:

header("Cache-Control: no cache"); 
session_cache_limiter("private_no_expire"); 
+0

dove dobbiamo aggiungere queste linee? – user3663

+0

@ user3663 L'ho usato su tutte le pagine ma potrebbe funzionare solo sulle pagine dell'interfaccia, ad es. view.php in merito alla domanda dell'OP. –

-1

è necessario rimuovere la richiesta che POST dati dalla storia del browser

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

Vedi this risposta

Inoltre si può seguire il modello Post/Redirect/Get.

0

Una soluzione alternativa che funziona anche se/quando la pagina viene ricaricata implica il controllo dell'originalità del post utilizzando $ _SESSION. In poche parole, controlla una stringa unica o casuale.

Nel modulo, aggiungere un elemento con un valore impostato utilizzando rand() o microtime():

<input type="hidden" name="formToken" value="<?php echo microtime();?>"/> 

E quindi avvolgere la funzione PHP per convalidare e analizzare i dati del modulo in un blocco if:

if(!isset($_SESSION['formToken']) || $_POST['formToken'] !== $_SESSION['formToken'])){ 
     $_SESSION['formToken'] = $_POST['formToken']; 
     /*continue form processing */ 
}