Come evitare il reinvio del form al refresh della pagina
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! :)
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.

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?

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

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

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

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.

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().

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).

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 :)

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 :)

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ò.

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
