web-dev-qa-db-fra.com

Comment puis-je empêcher les boutons Retour et Actualiser de soumettre à nouveau mon formulaire?

Je fais du développement web. 

J'ai une page à faire avec carte de crédit, qui lorsque l'utilisateur clique sur "actualiser" ou "retour", la transaction sera effectuée une fois de plus, ce qui est indésirable.

Ceci inclut le bouton en haut à gauche "Précédent" et "Actualiser" du navigateur, "clic droit-> Actualiser/Précédent", appuyez sur la touche "F5" . Cette opération doit être effectuée sur certaines pages cgi uniquement, pas toutes.

Cela peut-il être fait en utilisant Javascript? Ou toute autre méthode?

22
sytee

La méthode standard consiste à procéder en 3 étapes. 

  1. la page de formulaire soumet des champs à la page de traitement
  2. page de traitement traite les données et redirige vers la page de résultat
  3. la page de résultats affiche uniquement les résultats, son rechargement ne fera aucun mal.
48
vartec

Cela casse le modèle d'expérience utilisateur de base du navigateur ... les utilisateurs devraient toujours pouvoir utiliser les boutons Actualiser et Précédent de leur navigateur. Vous recommandons de réparer votre page d'une autre manière.

Si vous mettez à jour votre question pour inclure le langage/la plate-forme/la technologie du serveur que vous utilisez, quelqu'un pourra peut-être suggérer une solution.

11
Richard Everett

Le simple fait de soumettre à nouveau le formulaire génère une transaction en double est préoccupant. Vous devriez avoir une sorte de vérification pour vous assurer que chaque soumission de données de formulaire est unique.

Par exemple, la page qui soumettrait le formulaire devrait recevoir un identifiant unique qui sera soumis avec le formulaire. La logique applicative doit alors être en mesure de reconnaître que le formulaire soumis a déjà été traité (étant donné que l'identifiant unique (ne sera plus le même) sera le même). Par conséquent, la seconde tentative est ignorée.

La «méthode standard» n'empêche toujours pas les clients de cliquer deux fois sur le bouton Précédent ... ou même de revenir en arrière et de soumettre à nouveau le formulaire s'ils ne pensent pas (pour une raison quelconque) qu'il a été traité.

8
James Camfield
  1. générer une chaîne aléatoire et la stocker en session,

  2. puis le sortir sur votre formulaire en tant que valeur cachée,

  3. vérifier la variable soumise et stocker, si les requêtes traitent votre demande,

  4. allez à 1.

5
Anonymous

Placez ce code sur la page du formulaire

Response.Cache.SetCacheability(HttpCacheability.NoCache);

Response.Cache.SetExpires(DateTime.Now-new TimeSpan(1,0,0));

Response.Cache.SetLastModified(DateTime.Now);

Response.Cache.SetAllowResponseInBrowserHistory(false);
3
Zoomer

Vous ne devez pas essayer de "bloquer" ces actions . Ce que vous devez faire est de vous assurer que rien ne se passe lorsque quelqu'un "double soumet" le formulaire.

2
andi

et dans certains navigateurs, vous ne pouvez même pas faire cela, et c’est bien!

1
Tobias

Le meilleur moyen consiste à avoir suffisamment de logique de traitement de session pour pouvoir reconnaître la deuxième (et ultérieure) tentative comme "ceci est simplement une nouvelle soumission" et l'ignorer.

1
Vatine

Je n'ai pas vu ça ici, alors le voici.

  1. Mettez un jeton unique dans le formulaire.
  2. Le bouton d'envoi déclenche une demande xmlhttp (ajax) adressée au serveur afin de créer une variable de session nommée d'après le jeton avec une valeur stockée de 1.
  3. La demande ajax soumet le formulaire après avoir reçu un changement d'état positif.
  4. Le script de traitement de formulaire recherche la variable de session avec la valeur stockée de 1.
  5. Le script supprime la variable de session et traite le formulaire.

Si la variable de session n'est pas trouvée, le formulaire ne sera pas traité. Étant donné que la variable est supprimée dès qu'elle est trouvée, le formulaire ne peut être exécuté qu'en appuyant sur le bouton d'envoi. Actualiser et retourner ne soumettra pas le formulaire. Cela fonctionnera sans l'utilisation d'une redirection.

1
Malcolm Cooper

J'ai trouvé le message ci-dessus Post/Redirect/Get un peu ambigu

Voici ce que j'ai suivi et j'espère que cela aidera quelqu'un à l'avenir

http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html

Le processus basé sur la solution ci-dessus est essentiellement le suivant:

  1. Soumettre de la page FORM à la page de traitement (ou à elle-même) 
  2. Gestion de la base de données ou du traitement des paiements, etc.
  3. Si nécessaire, stocke le message de retour de l'utilisateur dans une variable de session, des messages d'erreur possibles, etc.
  4. Effectuer une redirection d'en-tête vers la page de résultats (ou vers la page de formulaire d'origine). Si nécessaire, affiche un message personnalisé à partir de la page de traitement. Tels que "Le paiement par carte de crédit avec erreur a été rejeté" et la réinitialisation des variables de session.

Rediriger avec quelque chose comme:

header("HTTP/1.1 303 See Other");
header("Location: http://$_SERVER[HTTP_Host]/yourfilehere.php");
die();

La redirection d'en-tête initiera une requête GET sur "yourfilehere.php", car une redirection est simplement une "requête" pour extraire des données du serveur, PAS une POST qui envoie des données AU serveur. Ainsi, la redirection/GET empêche tout traitement ultérieur des bases de données/paiements après une actualisation. Le statut d'erreur 301 aidera à appuyer sur le bouton Précédent. 

Lecture utile:

  1. http://en.wikipedia.org/wiki/URL_redirection#HTTP_status_codes_3xx
  2. http://www.theserverside.com/news/1365146/Redirect-After-Post
  3. http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html
  4. https://en.wikipedia.org/wiki/HTTP#Request_methods
  5. http://en.wikipedia.org/wiki/Post/Redirect/Get
0
wired00

la solution de vartec: s résout le problème de rechargement, pas le problème de retour, voici donc une solution à ce problème:

  1. La page de formulaire définit une variable de session, par exemple session ("fromformpage") = 1
  2. La page de traitement vérifie la variable de session, si sa = "1", alors traite les données et redirige vers la page de résultat si autre que = "1" puis redirige simplement vers la page de résultat.
  3. La page de résultats définit la variable de session sur "".

Ensuite, si l'utilisateur appuie sur le bouton Précédent, la page de traitement ne refera pas le processus, mais uniquement une redirection vers la page de traitement.

0
Stefan

Il suffit de mettre ce javascript sur la section html de la page aspx au-dessus de la section head 

<script type = "text/javascript" >
function disableBackButton()
{
window.history.forward();
}
setTimeout("disableBackButton()", 0);
</script>

Nous devons le mettre sur la section html de la page que nous voulons empêcher les utilisateurs de visiter en appuyant sur le bouton Précédent

Le code complet de la page ressemble à ceci

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script type = "text/javascript" >
function disableBackButton()
{
window.history.forward();
}
setTimeout("disableBackButton()", 0);
</script>
</head>
<body onload="disableBackButton()">
<form id="form1" runat="server">
<div>
This is First page <br />
<br />
Go to Second page
<br />
<br />
<asp:LinkButton ID="LinkButton1" runat="server"
PostBackUrl="~/Default2.aspx">Go to Second Page
</asp:LinkButton></div>
</form>
</body>
</html>

Si vous utilisez firefox, utilisez plutôt que onload

Si vous souhaitez désactiver le bouton Précédent en utilisant le code derrière la page aspx, vous devez écrire ci-dessous le code mentionné Code C # derrière  

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
string strDisAbleBackButton;
strDisAbleBackButton = "<script language="javascript">\n";
strDisAbleBackButton += "window.history.forward(1);\n";
strDisAbleBackButton += "\n</script>";
ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "clientScript", strDisAbleBackButton);
} 

Nous pouvons également y parvenir en désactivant la mise en cache du navigateur ou en mettant en cache cette ligne de code, que ce soit dans un événement Page_load ou un événement Page_Init

protected void Page_Init(object Sender, EventArgs e)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1));
Response.Cache.SetNoStore();
}

Ce faisant, l'utilisateur obtiendra le message que la page a expiré en appuyant sur le bouton arrière du navigateur.

La démo est:

enter image description here

0
Ramesh Rajendran

Ce code fonctionne pour ne pas revenir de la page actuelle me .. 

Ici, je mets un code qui vous aide, pas ouvrir le menu contextuel et sur le rechargement du navigateur, vous demander de laisser une page ou non ...

J'essaie de demander, cliquez sur le bouton retour du navigateur

jQuery( document ).ready(function() {

    document.onkeydown = fkey;
    document.onkeypress = fkey
    document.onkeyup = fkey;

    var wasPressed = false;

    function fkey(e){
        e = e || window.event;
        //alert(e.keyCode);
        if( wasPressed ) return; 


        if (e.keyCode == 116 || e.keyCode == 8 || e.keyCode == 17) {
                     // alert("f5 pressed");
                      window.onbeforeunload = null;
                      return true;
                 }

    }
window.onbeforeunload = function (event) {
    var message = ''; // Type message here

    if (typeof event == 'undefined') {
        event = window.event;
    }
    if (event) {
        event.returnValue = message;
    }

    return message;
};

jQuery(function () {

    jQuery("a").click(function () {
        window.onbeforeunload = null;
    });

    jQuery(".btn").click(function () {
        window.onbeforeunload = null;
    });

    //Disable part of page
    $(document).on("contextmenu",function(e){
        return false;
    });
});});

Merci,

0
Bhavin Patel