2009-04-06 12 views
13

Ho il seguente codice sul mio sito (utilizzando PHP e Smarty) per cercare di evitare una forma di inviare nuovamente quando ho colpito f5:Evitare modulo di reinvio in php premendo F5

if ($this->bln_added == false) { 
    if (isset($_POST['submit'])) { 
     $this->obj_site->obj_smarty->assign('title', $_POST['tas_heading']); 
     $this->obj_site->obj_smarty->assign('desc', $_POST['tas_description']); 
    } 
} else { 
    $this->obj_site->obj_smarty->assign('title', ''); 
    $this->obj_site->obj_smarty->assign('desc', ''); 
    unset($_POST); 
} 

bln_added è false per impostazione predefinita, ma cambia in vero una volta che il modulo è stato inviato correttamente. Il titolo e la descrizione delle variabili smarty vengono utilizzati nel modello per mantenere il contenuto del modulo nel caso in cui vi sia un errore dell'utente e devono modificare ciò che hanno inserito.

Se il modulo viene inviato correttamente, imposta bln_added = true, quindi il secondo bit di codice non dovrebbe solo cancellare i campi del modulo, ma anche svuotare $ _POST. Ma se premo f5 i dati del post sono ancora lì.

Qualche idea?

risposta

38

Il tuo metodo potrebbe funzionare in teoria, ma c'è un modo molto più semplice.

Dopo aver inviato correttamente il modulo, eseguire un reindirizzamento. Non importa dove, ma cancellerà $ _POST.

header('Location: http://www.example.com/form.php'); 

Nel tuo caso, sembra che tu voglia reindirizzare alla pagina che stai già utilizzando. Aggiungi un parametro $ _GET all'URL se vuoi visualizzare un messaggio di conferma.

Spero che questo aiuti,

Tom

+3

Grande risposta, PRG è sicuramente la strada da percorrere: http://en.wikipedia.org/wiki/Post/Redirect/Get –

+0

Ho bisogno l'URL completo per l'intestazione? – wheresrhys

+0

L'ho appena provato ed è in conflitto con un'intestazione impostata da qualche altra parte nell'applicazione. Non ho scritto tutto così non ho idea di dove andare per fermarlo. – wheresrhys

6

Il modo migliore per gestire i moduli è utilizzare l'auto-inoltro e un reindirizzamento. Qualcosa di simile a questo:

if (isset($_POST)) { 
    // Perform your validation and whatever it is you wanted to do 
    // Perform your redirect 
} 

// If we get here they didn't submit the form - display it to them. 

Utilizzando la CodeIgniter framework:

function index() { 
    $this->load->library('validation'); 
    // Your validation rules 

    if ($this->form_validation->run()) { 
    // Perform your database changes via your model 
    redirect(''); 
    return; 
    } 
    // The form didn't validate (or the user hasn't submitted) 
    $this->load->view('yourview'); 
} 
0

Header redirect dopo post è necessaria, ma non sufficiente.

Nel lato PHP dopo aver inviato correttamente il modulo, eseguire un reindirizzamento. Per esempio. intestazione ('Posizione: http://www.example.com/form.php');

Ma non è abbastanza. Alcuni utenti premono il link due volte (doubleclick). È richiesto un JavaScript che disabiliti il ​​pulsante di invio dopo il primo clic.

1

Ho risolto questo (in php) da:

  1. sotto forma aggiungere un identificativo univoco (id + contatore) non in base al tempo() (!!!)

  2. post per un file separato (postform.php) che controllato per una sessione con tale identificatore univoco

  3. a) se la sessione con identificativo univoco non è stata trovata: posta al database e riempire sessione con identificatore univoco

    b) se è stata trovata seduta con identificatore univoco : non fare nulla

  4. dopo il verificarsi 3a/3b reindirizzamento alla pagina di risultato con un colpo di testa ('Località http://mydomain.com/mypage')

risultato è:
non ripresentare le azioni su entrambi aggiornamento/BackButton e inviare nuovamente solo avvertimento su doppio click BackButton (ma nessuna azione reinvio)

+0

Grazie, ho avuto un'idea di base, perché non dovremmo usare l'invio dei moduli nella stessa pagina.Le volte precedenti stavo usando il modulo di invio alla stessa pagina. Dopo aver gestito il modulo, lo reindirizzo a se stesso con alcuni parametri get. –

1

Usa Header posizione dopo l'azione di successo dopo

header('Location: '.$_SERVER['HTTP_REFERER']); 
2

È possibile riscrivere il modulo-presentare in AJAX -modo. Se devi mostrare contenuto HTML, restituiscilo in formato JSON e inseriscilo con JavaScript (ad esempio jQuery)

1

Funziona per me se utilizzo l'header() o exit() alla fine del mio codice , ad esempio, dopo aver salvato alcuni dati.

1

Il metodo migliore che ho trovato è l'utilizzo di javascript e css. Intestazione del metodo di reindirizzamento PHP comune ('Posizione: http://www.yourdomain.com/url); funzionerà, ma causare avvertimento "Attenzione: Non è possibile modificare le informazioni di intestazione - headers already sent" in diversi contesti e CMS come WordPress, Drupal ecc Quindi il mio suggerimento è quello di seguire il codice qui sotto

echo '<style>body{display:none;}</style>'; 
echo '<script>window.location.href = "http://www.siteurl.com/mysuccesspage";</script>'; 
exit; 

Il tag stile è importante in caso contrario, l'utente potrebbe ritenere che la pagina sia stata caricata due volte. Se usiamo il tag di stile con body display none e quindi aggiorniamo la pagina, l'esperienza dell'utente sarà identica all'intestazione php ('Location: ....);

Spero che questo vi aiuterà :)

0

Prova il mio uno, forse non è la soluzione migliore (fatto in fretta), ma ho prova e funziona. Testato su Chrome. Click to see how it looks BR

<?php 
session_start(); // Start session 
?> 
<html> 
<head> 
    <title> 
    Test 
    </title> 
</head> 
<body> 
    <form name="test" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post"> 
    <input type="text" name="name"><br> 
    <input type="submit" name="submit" value="Submit Form"><br> 
    </form> 

    <?php 

    if(isset($_POST['submit'])) 
    { 
    $_SESSION['name'] = $_POST['name']; // Assign $_POST value to $_SESSION variable 
     header('Location: refresh.php'); // Address of this - reloaded page - in this case similar to PHP_SELF 
    } else session_destroy(); // kill session, depends on what you want to do/maybe unset() function will be enough 

    if(isset($_SESSION['name'])) 
    { 
    $name = $_SESSION['name']; 

    echo "User Has submitted the form and entered this name : <b> $name </b>"; 
    echo "<br>You can use the following form again to enter a new name."; 
    } 
    ?> 
</body> 
</html> 
Problemi correlati