Come evitare il reinvio del form al refresh della pagina

20 apr 2013, 18:27:44
Visualizzazioni: 103K
Voti: 9

Ciao, ho un form che aggiunge allegati a un post, tuttavia quando il form viene inviato ovviamente non mostra il post con il nuovo allegato ma visualizza "il tuo file è stato caricato". Quando l'utente aggiorna la pagina (per cercare di visualizzare il nuovo allegato) il form viene inviato di nuovo!

È possibile (1) impedire che il form venga inviato di nuovo durante l'aggiornamento, (2) aggiornare automaticamente la pagina per visualizzare il post con il nuovo allegato?? (l'opzione 2 è molto migliore)

<?php $post_id = $post->ID;
if ( isset( $_POST['html-upload'] ) && !empty( $_FILES ) ) {
    require_once(ABSPATH . 'wp-admin/includes/admin.php');
    $id = media_handle_upload('async-upload', $post_id); //ID del post della pagina File Cliente
    unset($_FILES);
    if ( is_wp_error($id) ) {
        $errors['upload_error'] = $id;
        $id = false;
    }

    if ($errors) {
        echo "<p>Si è verificato un errore durante il caricamento del file.</p>";
    } else {
        echo "<p>Il tuo file è stato caricato.</p>";
    }
}

?>
<form id="file-form" enctype="multipart/form-data" action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="POST">

<p id="async-upload-wrap"><label for="async-upload">carica</label>
<input type="file" id="async-upload" name="async-upload"> <input type="submit" value="Carica" name="html-upload"></p>

<p><input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id ?>" />
<?php wp_nonce_field('client-file-upload'); ?>
<input type="hidden" name="redirect_to" value="<?php echo $_SERVER['REQUEST_URI']; ?>" /></p>

<p><input type="submit" value="Salva tutte le modifiche" name="save" style="display: none;"></p>
</form>

Grazie! :)

0
Tutte le risposte alla domanda 9
5
12

Invece di…

} else {
    echo "<p>Il tuo file è stato caricato.</p>";
}

… reindirizza a un altro indirizzo in caso di successo:

} else {

    $new_url = add_query_arg( 'success', 1, get_permalink() );
    wp_redirect( $new_url, 303 );
    exit;
}

Il codice di stato 303 attiva una richiesta GET:

Questo metodo esiste principalmente per consentire a uno script attivato da POST di reindirizzare l'user agent a una risorsa selezionata. Il nuovo URI non è un riferimento sostitutivo per la risorsa originariamente richiesta. La risposta 303 NON deve essere memorizzata nella cache, ma la risposta alla seconda richiesta (reindirizzata) potrebbe essere memorizzabile.

Nel gestore del form, controlla prima se $_GET['success'] è impostato e il suo valore è 1, quindi stampa un messaggio di successo. Il visitatore può ricaricare questa pagina più e più volte – e nulla verrà inviato.

20 apr 2013 18:34:57
Commenti

Sfortunatamente non ha funzionato, e non ho idea del perché perché quel php si blocca (solo per confermare, tutto quello che dovevo fare era sostituire l'echo?

ameeromar ameeromar
20 apr 2013 19:40:33

Devi inviare l'header prima che qualsiasi output venga inviato al browser.

fuxia fuxia
20 apr 2013 19:42:06

quindi mettere il pezzo di codice php nell'header?

ameeromar ameeromar
26 apr 2013 16:02:14

@ameeromar Sì. Tutta l'elaborazione dei dati dovrebbe essere completata prima di iniziare a generare l'output.

fuxia fuxia
26 apr 2013 16:12:29

Questo funziona in WP e il 303 è un codice di reindirizzamento corretto in questo caso.

skobaljic skobaljic
29 ago 2021 17:09:54
1

Fondamentalmente, l'idea generale è reindirizzare l'utente verso altre pagine dopo l'invio del modulo, il che impedirebbe la risottomissione del modulo al refresh della pagina. Ma se hai bisogno di mantenere l'utente sulla stessa pagina dopo che il modulo è stato inviato, puoi farlo in diversi modi.

Azzera i Dati del Modulo

Un modo per evitare la risottomissione del modulo al refresh della pagina è azzerare i dati del modulo dopo l'invio, in modo che la variabile che contiene i dati del modulo diventi vuota, e racchiudere il blocco di codice di elaborazione del modulo in un controllo per verificare se il modulo è vuoto.

if(!empty($_POST) && $_SERVER['REQUEST_METHOD'] == 'POST'){
   $data = // codice di elaborazione qui
   unset $data;
}

Questo renderà $data vuota dopo l'elaborazione e la prima condizione impedirà la risottomissione del modulo al refresh della pagina.

Javascript

Questo metodo è abbastanza semplice e blocca la richiesta di risottomissione del modulo al refresh una volta che il modulo è stato inviato. Basta inserire questa riga di codice javascript nel footer del tuo file e vedrai la magia.

<script>
if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}
</script>

Per maggiori informazioni su queste query, puoi visitare questo link.

11 mag 2018 11:54:20
Commenti

Il tuo codice javascript ha funzionato, ma spero di capire il php, come si memorizza il codice di elaborazione in una variabile?

Enjabain Enjabain
13 mag 2023 14:55:53
0

Ho avuto lo stesso problema ed era "complicato" dal fatto che reindirizzo tutti gli URL a un singolo file .php. Si è rivelato che tutto ciò che dovevo fare per risolverlo era inserire il seguente frammento di codice prima che qualsiasi HTML venga scritto nella pagina.

<?php
if (isset($_POST['mypostvar']) && isset($_SERVER['REQUEST_URI']))
{
    [elabora i dati post in 'mypostvar']
    header ('Location: ' . $_SERVER['REQUEST_URI']);
    exit();
}
?>

Questo reindirizzerà alla stessa pagina dopo che i dati post saranno stati elaborati come desideri. Dopo il reindirizzamento, i dati post originali scompariranno e non attiveranno il ri-invio. La funzione 'header()' funzionerà solo se la inserisci prima che qualsiasi cosa venga scritta nella pagina. exit() è necessario.

Devi elaborare i dati post prima di posizionare header().

12 set 2013 02:41:14
1

Ho risolto questo problema utilizzando l'azione template_redirect (sia in un plugin che nel file functions.php del tuo tema).

add_action('template_redirect','myfunction') ;

function myfunction() { 
  global $post;
  $post_id = $post->ID;
  if ( isset( $_POST['html-upload'] ) && !empty( $_FILES ) ) {
     require_once(ABSPATH . 'wp-admin/includes/admin.php');
     $id = media_handle_upload('async-upload', $post_id); //ID del post della pagina File del Cliente
     unset($_FILES);
     if ( is_wp_error($id) ) {
        $errors['upload_error'] = $id;
        $id = false;
    }

  }
  $error = ($errors) ? 1 : 0;
  wp_redirect( "/?p={$post_id}?errors={$error}",301);
}

Poi nella tua pagina puoi verificare gli errori

if ($_GET['errors']) {
    echo "<p>C'è stato un errore durante il caricamento del tuo file.</p>";
} else {
    echo "<p>Il tuo file è stato caricato correttamente.</p>";
}

(Non ho testato questo codice.. dovrebbe darti un buon punto di partenza).

12 set 2013 04:33:37
Commenti

Con global $post nella prima riga, le probabilità che questa funzione funzioni aumenteranno...

gmazzap gmazzap
12 set 2013 05:40:44
0

Puoi anche verificare $_SERVER['REQUEST_METHOD'] === 'POST' per assicurarti che la pagina sia stata ricaricata tramite POST prima di elaborare il modulo.

if ( $_SERVER['REQUEST_METHOD'] === 'POST' )
{
   // Esegui le operazioni
}
13 set 2013 01:40:02
0

Un modo più semplice è rimuovere l'azione dal tuo form e avere un'azione nascosta, ad esempio:

<html>
<form action="" method="post><input type="text" name="name" />
<input type="submit" value="Invia" />
<input type="hidden" name="action" value="Invia" />
</form>
</html>

Fai in modo che il tuo controller controlli la validità e gli invii, quindi per verificare se il form è stato inviato:

<?php 
if (isset($_POST['action']) && $_POST['action'] == 'Invia'){
   //qui dovresti aggiungere il codice per validare l'input dell'utente
   //se tutto ok invia il form
   header('Location: .'); //reindirizza al controller senza ripetere l'invio
}
?>

Questo metodo è molto utile per script in cui si aggiungono o rimuovono record in una pagina di amministrazione, poiché ricarica la pagina senza ripetere l'invio e il record rimosso o aggiunto verrà visualizzato correttamente :)

10 gen 2016 00:06:52
0

Il metodo migliore che ho trovato è utilizzare javascript e css. Il comune metodo di reindirizzamento php header('Location: http://www.yourdomain.com/url); funziona ma causa l'avviso "Warning: Cannot modify header information - headers already sent" in diversi framework e cms come WordPress, Drupal ecc. Quindi il mio suggerimento è 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 style è importante altrimenti l'utente potrebbe avere la sensazione che la pagina venga caricata due volte. Se usiamo il tag style con body display none e poi ricarichiamo la pagina, l'esperienza utente sarà la stessa di php header('Location: ....);

Spero che questo possa aiutare :)

23 giu 2017 15:33:06
0

Soluzione 1: Se stai inserendo un post in un post type, puoi generare un codice casuale utilizzando la funzione PHP rand() e salvare il codice durante l'inserimento del post. Imposta anche lo stesso codice nella variabile $_POST['uniqueid'].

Poi verifica durante l'inserimento se l'uniqueid corrente è già presente nei post o meno, puoi farlo utilizzando wp_query().

Soluzione 2: Reindirizza a un'altra pagina utilizzando JavaScript. Tieni presente però che l'utente può tornare indietro alla pagina e, al refresh, il post verrà salvato nuovamente. Per questo problema, la prima soluzione è la migliore.

Soluzione 3: Utilizza Ajax per inserire il post, così non ci saranno problemi di questo tipo. Ma se vuoi conteggiare le visualizzazioni della pagina, non è una buona idea, forse è utile solo per Google Adsense.

Ho cercato di aiutare basandomi sulla mia esperienza. Se qualcuno ha bisogno del codice per risolvere il problema, basta chiedere, lo condividerò.

1 mag 2020 01:05:04
0
-2

il modo semplice e facile per farlo in php. esempio qui:

non dimenticare i tag html (questo form non lo permette qui quindi uso [questi])

$firstname = $post[firstname]

$lastname = $post[lastname]

[form action="here.php" method="post"]

nome [input type='firstname' name='firstname']

cognome [input type='text' name='lastname']

[input type=submit value=invia]
[/form]

if($firstname==""||$lastname=="")
{

echo "il nome e cognome sono vuoti";

}
else
{

mysql_query("INSERISCI QUI IL TUO DATABASE");

header("Location:here.php");

}

questo è come mantenere i dati inseriti nel database evitando di postare gli stessi dati due volte al refresh della pagina

7 dic 2014 17:14:57