php - vider - rafraichir une page chrome




Comment empêcher la resoumission de formulaire lorsque la page est actualisée(F5/CTRL+R) (11)

J'ai un formulaire simple qui soumet du texte à ma table SQL. Le problème est que, après que l'utilisateur a soumis le texte, il peut actualiser la page et les données sont soumises à nouveau sans remplir à nouveau le formulaire. Je pourrais rediriger l'utilisateur vers une autre page après la soumission du texte, mais je souhaite que les utilisateurs restent sur la même page.

Je me souviens avoir lu quelque chose sur le fait de donner à chaque utilisateur un ID de session unique et de le comparer avec une autre valeur qui a résolu le problème que j'ai, mais j'ai oublié où c'est.


  1. Utilisez l'en-tête et redirigez la page.

    header("Location:your_page.php"); Vous pouvez rediriger vers la même page ou vers une page différente.

  2. Détruisez $ _POST après l'avoir inséré dans la base de données.

    unset($_POST);


Après l'avoir inséré dans la base de données, appelez la méthode unset () pour effacer les données.

unset ($ _ POST);

Pour empêcher l'insertion des données d'actualisation, effectuez une redirection de page vers la même page ou vers une autre page après l'insertion d'enregistrement.

header ('Location:'. $ _ SERVER ['PHP_SELF']);


Comment empêcher la resoumission de formulaire php sans redirection. Si vous utilisez $ _SESSION (après session_start) et un formulaire $ _POST, vous pouvez faire quelque chose comme ceci:

if ( !empty($_SESSION['act']) && !empty($_POST['act']) && $_POST['act'] == $_SESSION['act'] ) {
  // do your stuff, save data into database, etc
}

Dans votre formulaire html, mettez ceci:

<input type="hidden" id="act" name="act" value="<?php echo ( empty($_POST['act']) || $_POST['act']==2 )? 1 : 2; ?>">
<?php
if ( $_POST['act'] == $_SESSION['act'] ){
    if ( empty( $_SESSION['act'] ) || $_SESSION['act'] == 2 ){
        $_SESSION['act'] = 1;
    } else {
        $_SESSION['act'] = 2;
    }
}
?>

Ainsi, chaque fois que le formulaire est soumis, un nouvel acte est généré, stocké en session et comparé à l'acte de publication.

Ps: si vous utilisez un formulaire Get, vous pouvez facilement modifier tous les POST avec GET et cela fonctionne aussi.


Fondamentalement, vous devez rediriger hors de cette page, mais il peut toujours faire un problème pendant que votre Internet lent (rediriger l'en-tête de côté serveur)

Exemple de scénario de base:

Cliquez deux fois sur le bouton Envoyer

Façon de résoudre

  • Côté client

    • Désactiver le bouton Envoyer une fois que le client clique dessus
    • Si vous utilisez Jquery: Jquery.one
    • Modèle PRG
  • Du côté serveur

    • Utilisation de l'horodatage / horodatage de hachage différencié en fonction de l'envoi de la requête.
    • Nous demandons des jetons. Lorsque les charges principales attribuent une requête tocken temporaire qui, si elle est répétée, est ignorée.

J'ai trouvé la solution de contournement suivante. Vous pouvez échapper à la redirection après le traitement de la requête POST en manipulant history objet d' history .

Donc vous avez le formulaire HTML:

<form method=POST action='/process.php'>
 <input type=submit value=OK>
</form>

Lorsque vous traitez ce formulaire sur votre serveur, au lieu de rediriger l'utilisateur vers /the/result/page en configurant l'en-tête Location comme ceci:

$cat process.php
<?php 
     process POST data here
     ... 
     header('Location: /the/result/page');
     exit();
?>

Après le traitement des données POST ed, vous affichez un petit <script> et le résultat /the/result/page

<?php 
     process POST data here
     render the <script>         // see below
     render `/the/result/page`   // OK
?>

Le <script> vous devriez rendre:

<script>
    window.onload = function() {
        history.replaceState("", "", "/the/result/page");
    }
</script>

Le résultat est:

Comme vous pouvez le voir, les données du formulaire sont POST au script process.php .
Ce processus de script POST ed data et rendering /the/result/page à la fois avec:

  1. pas de redirection
  2. pas de données POST lorsque vous actualisez la page (F5)
  3. pas de POST lorsque vous naviguez vers la page précédente / suivante via l'historique du navigateur

UPD

Comme une autre solution je demande la fonctionnalité demande à l'équipe Mozilla FireFox pour permettre aux utilisateurs de configurer l'en NextPage tête NextPage qui fonctionnera comme l'en-tête de Location et rendre post/redirect/get pattern obsolète.

En bref. Lorsque le formulaire de processus du serveur POST données POST avec succès, il:

  1. Configurer l'en NextPage tête NextPage au lieu de Location
  2. Rendre le résultat du traitement des données de formulaire POST comme il le ferait pour la requête GET dans le modèle post/redirect/get

Le navigateur à son tour quand voir l'en NextPage tête NextPage :

  1. Ajuster window.location avec la valeur NextPage
  2. Lorsque l'utilisateur actualise la page, le navigateur négociera la demande GET vers NextPage au lieu des données de formulaire POST .

Je pense que ce serait excellent s'il était mis en œuvre, non? =)


Je voudrais également souligner que vous pouvez utiliser une approche javascript, window.history.replaceState pour empêcher une resoumettre sur le bouton de rafraîchissement et de retour.

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

Preuve de concept ici: https://dtbaker.net/files/prevent-post-resubmit.php

Je recommanderais toujours une approche Post / Redirect / Get, mais ceci est une nouvelle solution JS.


Pourquoi ne pas simplement utiliser la variable $_POST['submit'] comme une instruction logique pour sauvegarder ce qui est dans le formulaire. Vous pouvez toujours rediriger vers la même page (au cas où ils se rafraîchiraient, et quand ils go back dans le navigateur, la variable submit post ne serait plus définie. Assurez-vous simplement que votre bouton submit a un name et un id de submit .


Un moyen assez infaillible est de mettre en œuvre un identifiant unique dans la publication et le mettre en cache dans le

<input type='hidden' name='post_id' value='".createPassword(64)."'>

Ensuite, dans votre code, faites ceci:

if( ($_SESSION['post_id'] != $_POST['post_id']) )
{
    $_SESSION['post_id'] = $_POST['post_id'];
    //do post stuff
} else {
    //normal display
}

function createPassword($length)
{
    $chars = "abcdefghijkmnopqrstuvwxyz023456789";
    srand((double)microtime()*1000000);
    $i = 0;
    $pass = '' ;

    while ($i <= ($length - 1)) {
        $num = rand() % 33;
        $tmp = substr($chars, $num, 1);
        $pass = $pass . $tmp;
        $i++;
    }
    return $pass;
}

Utiliser le modèle Post / Redirect / Get de Keverw est une bonne idée. Cependant, vous ne pouvez pas rester sur votre page (et je pense que c'est ce que vous demandiez?). En outre, il peut parfois fail :

Si un utilisateur Web est actualisé avant la fin de la soumission initiale en raison du décalage du serveur, il en résulte une demande HTTP POST en double dans certains agents d'utilisateur.

Une autre option serait de stocker dans une session si le texte doit être écrit dans votre base de données SQL comme ceci:

if($_SERVER['REQUEST_METHOD'] != 'POST')
{
  $_SESSION['writeSQL'] = true;
}
else
{
  if(isset($_SESSION['writeSQL']) && $_SESSION['writeSQL'])
  {
    $_SESSION['writeSQL'] = false;

    /* save $_POST values into SQL */
  }
}

Utilisez le modèle Post / Redirect / Get. Post/Redirect/Get

Avec mon site Web, je vais stocker un message dans un cookie ou une session, rediriger après la publication, lire le cookie / session, puis effacer la valeur de cette session ou cookie variable.


vous pouvez changer la forme resoumettre via la variable de session

vous devez d'abord définir rand () dans la zone de texte et $ _SESSION ['rand'] sur la page du formulaire

<form action="" method="post">
  <?php
   $rand=rand();
   $_SESSION['rand']=$rand;
  ?>
 <input type="hidden" value="<?php echo $rand; ?>" name="randcheck" />
   Your Form's Other Field 
 <input type="submit" name="submitbtn" value="submit" />
</form>

Après avoir coché $ _SESSION ['rand'] avec la zone de texte $ _POST ['randcheck'] value

         if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand'])
          {
         //Your Code here
         }




form-submit