8765 sujets

Développement web côté serveur, CMS

Bonjour,

J'ai un formulaire de contact qui ne renvois pas sur une autre page, d'où mon problème avec le bouton actualiser, comment faire pour que le formulaire ne sois pas à nouveau renvoyer avec le bouton actualiser ?

Exemple sans les contrôles JS :
<html>
<head>
	<title>Formulaire</title>
</head>
<body>
	<?php
		$erreur = '';
	
		if (isset($_POST['email'])){
			if (trim($_POST['email']) != ''){
				$email = $_POST['email'];
			}else{
				$erreur = $erreur . 'Email Obligatoire!<br/>';
			}
			
			if (isset($_POST['message']) && trim($_POST['message']) != ''){
				$message = $_POST['message'];
			}else{
				$erreur = $erreur . 'Message Obligatoire!<br/>';
			}
			
			if ($erreur != ''){
				echo $erreur;
			}else{
				echo 'Message envoyer: ' . $_POST['email'] . ' ' . $_POST['message'];
				mail('mail@mail.com', 'message', $message, 'From:' . $email);
			}			
		}
	?>
	<hr/>
	<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME'] ?>">
		Votre Email:<br/>
		<input type="text" name="email" value="" /><br/>
		Votre message:<br/>
		<textarea rows="10" cols="50" name="message"><?php echo $message ?></textarea><br/>
		<input type="submit" value="Envoyer" />
	</form>
</body>
</html>

Formulaire dégrossi au max, ce que je voudrais éviter c'est que l'on puisse renvoyer 10000 le formulaire avec le bouton actualiser du navigateur, tout en restant sur la même page bien-sur.
Modifié par 3arly3F (16 Aug 2010 - 18:12)
Si tu souhaites limiter le nombre d'utilisations du formulaire je dirais d'utiliser simplement une petite variable de session...

Lorsque le formulaire est soumis la première fois, tu crées une variable de session initialisée à 1, à chaque fois que le formulaire est resoumis tu l'incrémentes. Et pour limiter le nombre de soumissions (par exemple à 5), tu commences ta page par un truc du genre


if(isset($_SESSION['compteur_soumissions']) && $_SESSION['compteur_soumissions']>=5)
     unset($_POST);
Je comprend pas la marche à suivre, j'ai beau vider le formulaire avec :
echo 'Message envoyer: ' . $_POST['email'] . ' ' . $_POST['message'];
mail('moi@mail.com', 'message', $message, 'From:' . $email);
$email = "";
$message = "";
Tu pourrais un peut développez ta solution ?
Modérateur
Bonjour,

Une fois le formulaire envoyé et traité, tu peux faire une redirection sur une page de confirmation différente. Le bouton actualiser ne permettrait alors que de rafraîchir la page de confirmation. Ce n'est pas suffisant pour empêcher l'abus, mais ça élimine au moins la resoumission par erreur via le bouton Actualiser.
Modifié par Tony Monast (16 Aug 2010 - 15:22)
D'après ta réponse, je suppose que la page en question est un formulaire de contact (envoi d'email).

Ce que je te propose c'est, par exemple, de limiter l'envoi à 3 email par personne.

Dans ta page, avant de faire quoi que ce soit, tu auras donc ceci :


session_start();

// on vérifie si le compteur existe, et si le formulaire a déjà été envoyé 3 fois.
if(isset($_SESSION['compteur_soumissions']) && $_SESSION['compteur_soumissions']>=3) 
     unset($_POST); // on vide les données post, la page s'affiche comme lors du premier acces. On peut aussi afficher une erreur

// on vérifie que tous les champs soient remplis
if(isset($_POST['nom']) && isset($_POST['email']) && isset($_POST['message'])){

     // ON ENVOIE LE MAIL
     // ON INCREMENTE LE COMPTEUR D'ENVOIS REALISES SI LE MAIL A ETE ENVOYE
     if(isset($_SESSION['compteur_soumissions']) $_SESSION['compteur_soumissions']++;
     else $_SESSION['compteur_soumissions'] = 1;
}elseif(isset($_POST['nom']) || isset($_POST['email']) || isset($_POST['message'])){
     // MESSAGE D'ERREUR => AU MOINS UN DES CHAMPS N'EST PAS REMPLI
}


Une autre solution qui t'évitera tout ennui c'est d'ajouter un capcha à ton formulaire.
Une dernière solution, c'est d'envoyer le formulaire via ajax => rafraichissement de page ne renverra pas les données
Modifié par pixelb (16 Aug 2010 - 15:32)
Tony Monast a écrit :
Bonjour,

Une fois le formulaire envoyé et traité, tu peux faire une redirection sur une page de confirmation différente. Le bouton actualiser ne permettrait alors que de rafraîchir la page de confirmation. Ce n'est pas suffisant pour empêcher l'abus, mais ça élimine au moins la resoumission par erreur via le bouton Actualiser.

Salut Tony,

C'est ce que je fais d'habitude, mais là je veux pas passer par une page de validation, j'ai trouver une solution, après sa vaut ce que sa vaut, en tout cas sa fonctionne, et puis les isset sur des superglobals hein, bon empty sa fonctionne Smiley sweatdrop

Code PHP en début de page bien-sur :

<?php

session_start();


if(!empty($_POST) OR !empty($_FILES))
{
    $_SESSION['save'] = $_POST ;
    $_SESSION['saveFILES'] = $_FILES ;
    
    $pageActu = $_SERVER['PHP_SELF'] ;
    if(!empty($_SERVER['QUERY_STRING']))
    {
        $pageActu .= '?' . $_SERVER['QUERY_STRING'] ;
    }
    
    header('Location: ' . $pageActu);
    exit;
}

if(isset($_SESSION['save']))
{
    $_POST = $_SESSION['save'] ;
    $_FILES = $_SESSION['saveFILES'] ;
    
    unset($_SESSION['save'], $_SESSION['saveFILES']);
}

?>
pixelb a écrit :
D'après ta réponse, je suppose que la page en question est un formulaire de contact (envoi d'email).

Ce que je te propose c'est, par exemple, de limiter l'envoi à 3 email par personne.

Dans ta page, avant de faire quoi que ce soit, tu auras donc ceci :


session_start();

// on vérifie si le compteur existe, et si le formulaire a déjà été envoyé 3 fois.
if(isset($_SESSION['compteur_soumissions']) && $_SESSION['compteur_soumissions']>=3) 
     unset($_POST); // on vide les données post, la page s'affiche comme lors du premier acces. On peut aussi afficher une erreur

// on vérifie que tous les champs soient remplis
if(isset($_POST['nom']) && isset($_POST['email']) && isset($_POST['message'])){

     // ON ENVOIE LE MAIL
     // ON INCREMENTE LE COMPTEUR D'ENVOIS REALISES SI LE MAIL A ETE ENVOYE
     if(isset($_SESSION['compteur_soumissions']) $_SESSION['compteur_soumissions']++;
     else $_SESSION['compteur_soumissions'] = 1;
}elseif(isset($_POST['nom']) || isset($_POST['email']) || isset($_POST['message'])){
     // MESSAGE D'ERREUR => AU MOINS UN DES CHAMPS N'EST PAS REMPLI
}


Une autre solution qui t'évitera tout ennui c'est d'ajouter un capcha à ton formulaire.
Une dernière solution, c'est d'envoyer le formulaire via ajax => rafraichissement de page ne renverra pas les données

Effectivement c'est une bonne alternative, 3 soumissions étant largement suffisante, merci Smiley smile
Salut,

ben je vois pas bien la différence (au niveau du rendu) entre une page de confirmation et un message du type (vous avez bien envoyé tel message). Smiley murf

D'autant que d'après ce que j'en comprends il n'est pas possible de modifier le mail du destinataire donc quel serait l'intérêt d'envoyer 10000 fois un message à la même adresse ? (à ceci près que tu ne fais aucun contrôle sur le mail : que se passe-t-il si dans le champ email je mets
From%3Aadresse1%40hotmail.fr%0D%0ACc%3Aadresse2%40hotmail.fr ?)

Pour finir, et en fonction de ta configuration, il me suffit de désactiver les cookies pour que les sessions ne fonctionnent plus et outrepasser la sécurité. S'il y a vraiment un souci il vaudrait mieux gérer le nombre d'envoi (par IP et/ou dans un temps donné) en BDD et se contenter d'une redirection (avec éventuellement les sessions pour réafficher les infos).
Le champs mail je vérifie le format :
function VerifierAdresseMail($mail) 
{ 
   $Syntaxe='#^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,6}$#'; 
   if(preg_match($Syntaxe,$mail)) 
      return true; 
   else 
     return false; 
}

Bref, ce que je veux c'est de ne pas passer par une page différente pour la validation de l'envoi du formulaire, coter client je passe par JS (jQuery), serveur PHP.

Maintenant c'est sur que JS, cookies, désactiver sa ne fonctionne plus, alors que me conseille tu pour éviter ce genre de problème ?
Salut,

À mon avis, le plus robuste pour éviter le problème du refresh de la page est de stocker les derniers envois dans une base de données et de remonter une erreur si l'utilisateur veut envoyer un message strictement identique à un message déjà envoyé.
3arly3F a écrit :
Le champs mail je vérifie le format
Ah OK.

3arly3F a écrit :
Bref, ce que je veux c'est de ne pas passer par une page différente
C'est bien ce que je te conseillais de faire mais au pire tu peux rediriger vers la même page après envoi du mail :
<?php
session_start(); // Uniquement pour afficher -éventuellement- les infos du mail qui a été envoyé

// Initialisation ou récupération des variables
$email = !empty($_POST['email']) ? trim($_POST['email']) : '';
$message = !empty($_POST['message']) ? trim($_POST['message']) : '';

$erreurs = array();

function VerifierAdresseMail($mail)  
{  
   $Syntaxe='#^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,6}$#';  
   if(preg_match($Syntaxe,$mail))  
      return true;  
   else  
     return false;  
}

if($_SERVER['REQUEST_METHOD']=='POST') {
	// email obligatoire
	if(empty($email)) {
		$erreurs[] = 'Email obligatoire.';
	} else if(!VerifierAdresseMail($email)) {
		$erreurs[] = 'Email invalide.';
	}
	// message obligatoire
	if(empty($message)) {
		$erreurs[] = 'Message obligatoire.';
	}
	// Aucune erreur...
	if(empty($erreurs)) {
		// envoi du mail...
		$_SESSION['email'] = $email;
		$_SESSION['message'] = $message;
		header('Location: '.htmlspecialchars($_SERVER['PHP_SELF'])); // Redirection vers la même page
		exit();
	}
}
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
<style type="text/css" media="screen">
.alerte {
	color: #FF0033;
	font-weight: bold;
}
</style>
</head>
<body>
<?php
if(!empty($erreurs)) {
	foreach($erreurs as $erreur) {
		echo '<p class="alerte">'.$erreur."</p>\n";
	}
}
?>
<?php if(!empty($_SESSION['email'])) : ?>
<p>Message envoyé :</p>
<p><strong>Email :</strong> <?php echo htmlspecialchars($_SESSION['email']); ?></p>
<p><strong>Message :</strong> <?php echo nl2br(htmlspecialchars($_SESSION['email'])); ?></p>
<?php
unset($_SESSION['email']);
unset($_SESSION['message']);

else:
?>
<form ...>
</form>
<?php endif; ?>
</body>
</html>


Edit: @Julien > +1
Modifié par Heyoan (16 Aug 2010 - 17:21)
Merci pour toutes ces réponses, effectivement avec beaucoup de pratique Smiley confus

@Heyoan, exactement ce que je voulais faire, mais bon entre vouloir et pouvoir, en tout cas problème résolu !

@Julien Royer, dans ce cas précis j'ai pas de BDD.