Cómo evitar el reenvío del formulario al actualizar la página

20 abr 2013, 18:27:44
Vistas: 103K
Votos: 9

Hola, tengo un formulario que agrega archivos adjuntos a una entrada, sin embargo, cuando el formulario se envía obviamente no muestra la entrada con el nuevo archivo adjunto mostrando "su archivo ha sido subido". Cuando el usuario actualiza la página (para tratar de mostrar su nuevo archivo adjunto) ¡el formulario se envía de nuevo!

¿Es posible (1) evitar que el formulario se envíe nuevamente al actualizar, (2) actualizar automáticamente la página para mostrar la entrada con su nuevo archivo adjunto? (la opción 2 es mucho mejor)

<?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 de la entrada de la página de Archivos del Cliente
unset($_FILES);
if ( is_wp_error($id) ) {
    $errors['upload_error'] = $id;
    $id = false;
}

if ($errors) {
    echo "<p>Hubo un error al subir su archivo.</p>";
} else {
    echo "<p>Su archivo ha sido subido.</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">subir</label>
<input type="file" id="async-upload" name="async-upload"> <input type="submit" value="Subir" 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="Guardar todos los cambios" name="save" style="display: none;"></p>
</form>

¡Gracias! :)

0
Todas las respuestas a la pregunta 9
5
12

En lugar de …

} else {
    echo "<p>Tu archivo ha sido subido.</p>";
}

… redirige a otra dirección en caso de éxito:

} else {

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

El código de estado 303 desencadena una solicitud GET:

Este método existe principalmente para permitir que la salida de un script activado por POST redirija el agente de usuario a un recurso seleccionado. El nuevo URI no es una referencia sustitutiva del recurso solicitado originalmente. La respuesta 303 NO DEBE ser almacenada en caché, pero la respuesta a la segunda solicitud (redirigida) podría ser almacenable en caché.

En tu manejador de formulario, verifica primero si $_GET['success'] está definido y su valor es 1, luego muestra un mensaje de éxito. El visitante puede recargar esta página una y otra vez – y no se enviará nada.

20 abr 2013 18:34:57
Comentarios

Desafortunadamente eso no funcionó, y no tengo idea de por qué porque ese código PHP sí se ejecuta (solo para confirmar, ¿todo lo que se supone que debía hacer era reemplazar el echo?)

ameeromar ameeromar
20 abr 2013 19:40:33

Tienes que enviar el encabezado antes de que cualquier salida haya sido enviada al navegador.

fuxia fuxia
20 abr 2013 19:42:06

¿Entonces coloco el fragmento de código PHP en el encabezado?

ameeromar ameeromar
26 abr 2013 16:02:14

@ameeromar Sí. Todo el procesamiento de datos debe realizarse antes de comenzar a generar la salida.

fuxia fuxia
26 abr 2013 16:12:29

Esto funciona en WP y 303 es un código de redirección correcto en este caso.

skobaljic skobaljic
29 ago 2021 17:09:54
1

Básicamente, la idea general es redirigir al usuario a otras páginas después del envío del formulario, lo que evitaría el reenvío del formulario al actualizar la página. Pero si necesitas mantener al usuario en la misma página después del envío del formulario, puedes hacerlo de varias maneras.

Eliminar los datos del formulario

Una forma de evitar el reenvío del formulario al actualizar la página es eliminar los datos del formulario después de su envío, de modo que la variable que almacena los datos del formulario quede vacía, y envolver tu bloque de código de procesamiento del formulario para verificar si el formulario está vacío.


if(!empty($_POST) && $_SERVER['REQUEST_METHOD'] == 'POST'){
   $data = // código de procesamiento aquí
   unset $data;
}

Esto dejará $data vacío después del procesamiento y la primera condición evitará el reenvío del formulario al actualizar la página.

Javascript

Este método es bastante fácil y bloquea la ventana emergente que solicita el reenvío del formulario al actualizar una vez que se ha enviado el formulario. Simplemente coloca esta línea de código JavaScript en el pie de página de tu archivo y verás la magia.


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

Para más consultas como esta, puedes visitar este enlace.

11 may 2018 11:54:20
Comentarios

Tu código JavaScript funcionó, pero espero entender el PHP, ¿cómo almacenas el código de procesamiento en una variable?

Enjabain Enjabain
13 may 2023 14:55:53
0

Tuve el mismo problema y se complicó por el hecho de que redirijo todas las URLs a un solo archivo .php. Resultó que todo lo que tenía que hacer para solucionarlo era insertar el siguiente fragmento de código antes de que se escribiera cualquier HTML en la página.

<?php
if (isset($_POST['mypostvar']) && isset($_SERVER['REQUEST_URI']))
{
    [procesar los datos POST en 'mypostvar']
    header ('Location: ' . $_SERVER['REQUEST_URI']);
    exit();
}
?>

Esto redirigirá a la misma página después de procesar los datos POST como deseas. Después de la redirección, los datos POST originales desaparecen y no volverán a activar el reenvío. La función 'header()' solo funcionará si la insertas antes de que se escriba cualquier cosa en la página. exit() es necesario.

Tienes que procesar los datos POST antes de colocar el header().

12 sept 2013 02:41:14
1

Resolví esto usando la acción template_redirect (ya sea en un plugin o en el archivo functions.php de tu 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 de la página de Archivos 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);
}

Luego en tu página puedes verificar si hay errores

if ($_GET['errors']) {
    echo "<p>Hubo un error al subir tu archivo.</p>";
} else {
    echo "<p>Tu archivo ha sido subido correctamente.</p>";
}

(No he probado este código.. debería darte un buen punto de partida).

12 sept 2013 04:33:37
Comentarios

Con global $post en la primera línea, las posibilidades de que esta función funcione aumentarán...

gmazzap gmazzap
12 sept 2013 05:40:44
0

También puedes verificar $_SERVER['REQUEST_METHOD'] === 'POST' para asegurarte de que la página se ha actualizado mediante POST antes de procesar el formulario.

if ( $_SERVER['REQUEST_METHOD'] === 'POST' )
{
   // Hacer algo
}
13 sept 2013 01:40:02
0

una forma más sencilla es eliminar la acción de tu formulario y tener una acción oculta, por ejemplo:

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

haz que tu controlador verifique la validez y los envíos para comprobar si se envió el formulario:

<?php 
if (isset($_POST['action']) && $_POST['action'] == 'Enviar'){
   //deberías agregar código para validar la entrada del usuario aquí
   //si todo está bien, envía el formulario
   header('Location: .'); //redirige al controlador sin reenviar
}
?>

este método es muy útil para scripts donde estás agregando o eliminando registros en una página de administración, ya que recargaría la página sin reenviar y el registro eliminado o agregado aparecería o desaparecería de la página :)

10 ene 2016 00:06:52
0

El mejor método que encontré es usar javascript y css. El método común de redirección php header('Location: http://www.yourdomain.com/url); funciona pero causa la advertencia "Warning: Cannot modify header information - headers already sent" en diferentes frameworks y CMS como WordPress, Drupal, etc. Por lo tanto, mi sugerencia es seguir el siguiente código:

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

La etiqueta style es importante porque, de lo contrario, el usuario puede sentir que la página se cargó dos veces. Si usamos la etiqueta style con body display none y luego refrescamos la página, la experiencia del usuario será la misma que con php header('Location: ....);

Espero que esto ayude :)

23 jun 2017 15:33:06
0

Solución 1: Si estás insertando una publicación en un tipo de publicación, simplemente genera un código aleatorio usando la función PHP rand() y guarda el código mientras insertas la publicación. También establece el mismo código en la variable $_POST['uniqueid'].

Luego verifica al insertar si el uniqueid actual ya existe en las publicaciones o no, puedes hacer esto usando wp_query().

Solución 2: Redirige a otra página usando JavaScript. Pero ten en cuenta que el usuario puede volver a la página y al refrescar se guardará la publicación nuevamente. Para este problema, la primera solución es la mejor.

Solución 3: Usa AJAX para insertar la publicación, no habrá problemas como este. Pero si quieres contar visitas a la página, no es una buena idea, tal vez para Google Adsense.

Solo intenté ayudar desde mi experiencia. Si alguien necesita código para solucionar el problema, solo pregunte, lo compartiré.

1 may 2020 01:05:04
0
-2

la forma simple y fácil de hacer esto en php. ejemplo aquí:

no olvides las etiquetas html (este formulario no lo permite aquí así que uso [esto])

$firstname = $post[firstname]

$lastname = $post[lastname]

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

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

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

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

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

echo "el nombre y apellido están vacíos";

}
else
{

mysql_query("TU INSERCIÓN DE BASE DE DATOS AQUÍ");

header("Location:here.php");

}

así es como mantener los datos ingresados en la base de datos para evitar publicar la misma información dos veces al actualizar la página

7 dic 2014 17:14:57