Php empêche la soumission du formulaire. Comment puis-je empêcher un formulaire de renvoyer un message ? Empêcher les resoumissions de formulaires à l'aide d'une redirection côté client

À un moment donné, j'étais intrigué par la question de savoir comment protéger les pages du site contre la soumission répétée de données de formulaire lors d'une mise à jour de page (s'il y avait eu une soumission avant cela, bien sûr).
Tous les webmasters et développeurs savent probablement que si vous avez cliqué sur le bouton « envoyer » sur un site Web en remplissant un formulaire, après la soumission, si vous essayez d'actualiser la page, le navigateur affichera un message confirmant le renvoi.
Dans certains cas, cela peut être inacceptable. Par exemple, dans le cas de la forme élémentaire retour. Lorsque l'utilisateur a rempli le formulaire et envoyé un message, puis, pour une raison connue de lui seul, a actualisé la page, la lettre a été renvoyée. Bien entendu, ce n’est peut-être pas un cas aussi mortel, mais c’est juste un exemple. Tout est beaucoup plus pénible, par exemple lors de l'envoi d'une commande dans une boutique en ligne.
Je me suis donc demandé comment trouver une solution à ce problème et j'ai réalisé qu'il n'y avait qu'une seule solution : utiliser une redirection après avoir soumis le formulaire d'en-tête (« emplacement : adresse »). Ceux. C’est simple – après l’envoi, on appelle une redirection (vous pouvez même aller sur la même page) et c’est tout ! La mise à jour de la page sera propre, sans aucun POST ni GET terminés.

Tout irait bien, mais personnellement, j'ai rencontré quelques problèmes avec cela. Ils sont les suivants. Auparavant, sans utiliser de redirections, le mécanisme d'envoi de données sur mes sites fonctionnait comme suit :
L'utilisateur remplit le formulaire, clique sur "envoyer", le script accepte les données envoyées, vérifie leur exactitude (validité, complétion des données requises, etc.) et donne une réponse - soit l'opération a réussi, soit une erreur s'est produite et une liste d'erreurs (par exemple : erreur - Le champ « nom » n'est pas renseigné. Et sur la page d'envoi, le message correspondant s'affiche : l'envoi est réussi ou non.
Si la soumission échoue, le formulaire reste à l'écran et ses champs sont remplis avec les données saisies par l'utilisateur. Ceux. les données sont extraites de la variable $_POST (si la méthode est POST) et placées dans les champs appropriés (c'est-à-dire renvoyées de la publication vers ses champs afin de ne pas les saisir à nouveau). Après tout, tout le monde est ennuyé lorsque vous avez rempli un formulaire, et à Dieu ne plaise que vous ayez saisi quelque chose de manière incorrecte, et lorsque vous essayez de vous l'envoyer, un message est donné indiquant que quelque chose a été mal rempli, et le formulaire est mis à jour et est vide encore. Et à cause d'un champ mal rempli, vous devez le remplir à nouveau.
Ainsi, comme je l'ai déjà dit, en cas d'échec, le formulaire reste rempli avec les données extraites de $_POST, et l'utilisateur peut corriger les données incorrectes et soumettre à nouveau le formulaire.
Tout allait bien et tout fonctionnait.
Mais ensuite je l'ai envoyé par redirection et il s'est avéré qu'après avoir cliqué sur le bouton « envoyer », si le remplissage échouait, le formulaire était mis à jour et les champs remplis ne pouvaient plus y rester, car Auparavant, ils étaient automatiquement remplis à partir du tableau $_POST, mais maintenant, après la redirection, $_POST était effacé comme s'il n'y avait pas d'envoi.
Mais il y avait aussi une issue à cette affaire. Utilisez des séances. Ceux. Avant d'appeler l'en-tête, transférez les données du POST vers les variables de session et n'utilisez ensuite celles-ci qu'après la redirection.
En conséquence, le code est devenu beaucoup plus compliqué. Le débogage est devenu plus compliqué car En général, il est difficile de déterminer ce qui arrive aux fonctions au moment où se produit la redirection. Si vous avez fait une erreur dans les codes (qui apparaissent précisément au moment de l'envoi), alors ils ne seront même pas affichés, car une redirection se produira et vous ne verrez même pas le message d’erreur.
En général, après avoir implémenté header dans mes codes, il est devenu plus difficile pour moi de travailler avec mes applications. Le développement/raffinement/recherche d’erreurs est devenu plus compliqué. Mais je ne peux pas non plus refuser cela.
Et je continue de me demander : existe-t-il d’autres solutions, plus élégantes ?

Je reçois souvent des questions concernant l’annulation des resoumissions de formulaires. Par exemple, vous avez créé un formulaire pour ajouter un commentaire et ajouté un gestionnaire à la même page. Ensuite, lors de l'ajout d'un commentaire, celui-ci est ajouté avec succès, mais dès que l'utilisateur appuie sur F5, le formulaire sera à nouveau soumis. Et l'utilisateur peut facilement appuyer sur F5 si la page prend beaucoup de temps à se charger. En conséquence, au lieu d'un commentaire, il y en aura jusqu'à 2, voire plus. Dans cet article, je vais montrer comment cela peut être évité.

Tout d’abord, examinons le problème plus en détail en utilisant ce code comme exemple :









En cliquant sur le bouton "Carré", vous verrez le résultat du script. Mais dès que l'utilisateur appuie ensuite sur F5, le script sera à nouveau exécuté. Dans ce cas, ce n'est pas aussi critique que l'ajout d'un commentaire, cependant, pourquoi avez-vous besoin d'une charge supplémentaire sur le serveur ?

Parlons maintenant des moyens de résoudre ce problème. La première consiste à séparer le script de traitement dans un fichier séparé. Ensuite, dans l'attribut action de la balise form, vous devez ajouter le chemin d'accès à ce script. Et le script lui-même doit enregistrer le résultat de ses actions quelque part, ou les variables qui sont entrées dans le script, puis le rediriger. En général, regardez le code du script :

Et le code de la page avec le formulaire ressemblera désormais à ceci :









L'inconvénient de cette approche est évident : vous devez créer un autre fichier pour un script aussi simple. Par conséquent, je vous parle de la deuxième méthode, pour éviter de soumettre à nouveau le formulaire :









Ici, le traitement a lieu à nouveau dans le même fichier, mais la principale différence est la présence d'une redirection vers la même page à la fin. Par conséquent, la page se rechargera après la soumission du formulaire et le navigateur n'invitera pas l'utilisateur à soumettre à nouveau le formulaire lorsqu'il appuiera sur F5.

Permettez-moi de résumer comment annuler la resoumission d'un formulaire :

  • Ou effectuez le traitement dans fichier séparé, puis redirigez-vous à partir de là.
  • Ou effectuez le traitement dans le même fichier que le formulaire, mais après le traitement, effectuez une redirection vers la même page.

C'est ainsi que cela se fait dans des scripts simples. Et dans les cas complexes, la même chose se produit en fin de compte.

Disons que nous créons un script qui accepte les données d'un formulaire soumis à l'aide de la méthode POST. Le script a reçu les données, les a traitées et a affiché une page avec le résultat. Mais si l'utilisateur décide de rafraîchir la page à ce moment, il verra un message comme celui-ci :

Pour afficher cette page, Firefox doit envoyer des informations qui répéteront toute action effectuée précédemment (par exemple, une demande de recherche ou un achat en ligne).

Et deux boutons. Cliquer sur l’un d’eux renverra les données, ce qui est souvent indésirable. Cliquer sur le second ne rafraîchira pas la page. En tout cas, l’utilisateur ne se sent pas bien face à un tel message. Les utilisateurs n’aiment généralement pas toutes sortes de fenêtres pop-up.

Pour commencer, je vais vous montrer le scénario que nous allons finaliser.

Vous pouvez soumettre le formulaire une fois, puis appuyer sur Ctrl+R et voir la fenêtre malheureuse. Débarrassons-nous-en.

Mais d'abord, un mot du sponsor du post - un site avec du contenu utile pour téléphones Samsung, qui propose des thèmes pour Samsung gt s5230, des fonds d'écran et d'autres éléments.

Empêcher la resoumission du formulaire à l'aide de la redirection du serveur

Pour empêcher que les données du formulaire soient renvoyées, vous pouvez effectuer une redirection du serveur. Cela se fait en envoyant au navigateur un en-tête Location avec l'URL souhaitée. Par exemple, il devrait s'agir d'une page de remerciement pour avoir rempli le formulaire. Ensuite, nous écrirons quelque chose comme :

Dans ce cas, le serveur recevra les données, les traitera et, au lieu d'afficher le résultat, enverra le client vers une page où ce résultat sera affiché.

L'inconvénient de cette méthode est que l'utilisateur peut cliquer sur le bouton Précédent et revenir à la page redirigée. Elle le relancera et l'utilisateur ne pourra donc guère renvoyer deux pages au formulaire qu'il a initialement rempli.

Empêcher les resoumissions de formulaires à l'aide d'une redirection côté client

Une redirection client est appelée redirection client car elle se produit côté client. Autrement dit, dans le navigateur. La redirection client peut se produire à l'aide de JavaScript et de balises méta.

JavaScript a l'avantage d'écraser l'historique du navigateur, de sorte que même si l'utilisateur clique sur le bouton Précédent du navigateur, il ne reviendra pas à la page renvoyée par le gestionnaire de formulaire. Autrement dit, la fenêtre disparaîtra complètement. Mais certaines personnes ont désactivé JS.

Les balises META, quant à elles, ont l’avantage d’être polyvalentes. Ils redirigent tout le monde, toujours.

Il serait optimal de combiner ces deux méthodes. Comment - décrit par Alexander Shurkayev dans une note redirection optimale.

Nous utilisons sa méthode comme suit.

Essayons ! Maintenant, comme vous pouvez le constater, aucune fenêtre n'apparaît. Qu'avons-nous fait ? Nous avons vérifié. Si les données ont été reçues, nous affichons tout le nécessaire pour la redirection. En principe, après cela, vous pouvez même quitter, afin de ne pas charger le navigateur avec des données inutiles que personne ne verra de toute façon.