Avatar billede Peter Praktikant
06. juni 2004 - 19:52 Der er 20 kommentarer og
1 løsning

Mailform i PHP: Sikre at mail ikke sendes igen ved refresh

Hej eksperter
Jeg har lavet en mailform i php, denne forsøger jeg at sikre imod at nogle skulle synes det var sjovt at trykke refresh et antal gange og derved sende mailen det antal gange.
Jeg har forsøgt at unset($action) hvor action er et hidden inputfelt der bestemmer om formen skal udskrives eller om der skal sendes en mail.
Jeg har ligeledes forsøgt mig med en session-variable der sættes når mailen er sendt og derved ikke tillader at mailen sendes igen. Men dette synes jeg også giver nogle problemer, hvis f.eks brugeren trykker tilbage og ændrer i felterne og sender mailen igen bliver den ikke sendt. Jeg ville helst at alt blev unset, altså hele $_POST og alle variablerne. Men hver gang jeg trykker refresh får de værdierne igen.
Hvordan sikrer jeg bedst at en eller anden tosse ikke let kan sende den samme mail 400 gange uden at generere alt for mange normale brugere?

Udsnit af kode indsat.

<?php

$action = $_POST['action'];
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$subject = $_POST['subject'];
$message = $_POST['message'];

if(!$action){
    unset($_SESSION['email']);
    echoform("","","");//udskriver form.

} elseif((!$name || !$email || !$message)) {
    if(!$name)
        $nameError = "error";
    if(!$email)
        $emailError = "error";
    if(!$message)
        $messageError = "error";
   
    echoform("$nameError", "$emailError", "$messageError");
//udskriver hele formen med fejlbeskeder.
    echo "<br />Alle felter med rødt skal udfyldes.";

} else {
    if(!$_SESSION['email']){
            mail('xxxxx@xxxxx.dk',$subject,$message,"From: $name <$email>");
        $_SESSION['email'] = true;
    } else {
        echo "Din email er allerede sendt,<br />";
        echo "Gå til <a href='kontakt.php'>kontakt</a> for at sende en ny mail.";
    }
}
Avatar billede dennismp Nybegynder
06. juni 2004 - 19:59 #1
istedet for dette:
        echo "Din email er allerede sendt,<br />";
        echo "Gå til <a href='kontakt.php'>kontakt</a> for at sende en ny mail.";

kunne du jo lave en redirect
        header("Location: mailform.php");

så kan du jo øverst i se om count($_POST) == 0 - i så fald skriver du bare "Din mail er allerede sendt .. osv " .. hvis den ikke er 0 så gør du som nu.
Avatar billede Peter Praktikant
06. juni 2004 - 20:17 #2
Men count($_POST) vil være større end 0 lige så snart man har udfyldt et par felter og trykket submit, hvis alle felter så ikke er udfyldt udskriver jeg formen igen, dette ville ikke ske med din metode.
Jeg forstår bare ikke hvorfor jeg ikke kan unsette($_POST['action']) og $action. Det virker første gang man trykker F5, derefter bliver variablerne på mystisk vis sat igen.
Det kunne godt være jeg skulle løse det ved en redirect til en helt anden side når først mailen er sendt, så kan man så trykke på kontakt på ny i menuen.
Avatar billede dennismp Nybegynder
06. juni 2004 - 20:23 #3
$_POST array'et er bare en repræsentation af hvad brugeren har sendt dig. Når du unsetter gør du det jo kun på serveren, når brugeren trykker f5 igen så sender han hele molevitten og så har du problemet. Så du kan ikke bruge unset(). Jeg tror redirect er nemmest.
Avatar billede Peter Praktikant
06. juni 2004 - 20:25 #4
ahh, det er derfor. Jeg har bare et lille problem med redirect, siden er en del af en større side, den er inkluderet, så der er allerede smidt en masse output ud, derfor skal der ændres noget for at lave en redirect midt i det hele.
Avatar billede dennismp Nybegynder
06. juni 2004 - 20:31 #5
Den pæneste måde er at vente med at lave output indtil du ved om du vil redirecte eller ej.

Men ellers kan du bruge ob_start()/ob_end_clean()/ob_end_flush() til at sørge for at det ikke bliver et problem.
Avatar billede Peter Praktikant
06. juni 2004 - 21:01 #6
Som sagt, det er en fil der bliver inkluderet i en større skabelon, så hvis jeg skal undgå at lave output før jeg redirecter, så skal jeg lave om i skabelonen som jeg lige ser det. Eller er det kun indenfor den inkluderede fil det tæller, det kan jeg ikke helt finde ud af.
Avatar billede dennismp Nybegynder
06. juni 2004 - 21:05 #7
En nødløsning var måske at bruge javascript - selvom det så ikke sikre at alle bliver redirected videre..
Avatar billede Peter Praktikant
06. juni 2004 - 21:11 #8
Men hvad hvis jeg først unsetter alt og så laver en redirect til siden selv. Vil det så stadigvæk indebære at brugeren kan trykke F5 og derved sende emailen igen?
Jeg er meget lidt interesseret i at bruge javascript til dette her.
Ville du overhovedet gå op i at man vil kunne sende mailen flere gange ved at trykke F5?
Avatar billede dennismp Nybegynder
06. juni 2004 - 21:15 #9
Hvis du redirect'er til siden selv (du behøver ikke at unset()'et noget).. Så burde du få løst problemet.

Jeg kan godt forstå at du ikke er vild med javascript-løsningen :).

Det ved jeg ikke. Jeg er igang med et nyt framework til min hjemmesider, og der skal jeg have lavet en sådan redirect så man (delvist) undgår at får post'ed flere gange. Man kan jo ligeså godt undgå det hvis det er muligt. Så ja.
Avatar billede Peter Praktikant
06. juni 2004 - 21:43 #10
Det er bare lidt mærkeligt, for hvis jeg redirecter til php_self, så får jeg en about:blank frem på trods af jeg burde få formen frem igen.
Avatar billede Peter Praktikant
06. juni 2004 - 21:48 #11
Jeg tror jeg har fået det til at være som jeg gerne vil, jeg har lavet en kontakt2.php som jeg viderestiller til, denne viderestiller direkte til kontakt.php, så derved kommer den tomme form op hvis man refresher, også selvom man gør det mange gange.
Avatar billede Peter Praktikant
06. juni 2004 - 21:50 #12
Kan ikke helt gennemskue hvorfor jeg ikke kunne redirecte til kontakt.php direkte, men det kunne jeg ikke uden blot at få about:blank.
Avatar billede dennismp Nybegynder
06. juni 2004 - 21:53 #13
Det lyder underligt at du får about:blank. Kan det være en bug i IE ?
Avatar billede Peter Praktikant
06. juni 2004 - 22:08 #14
Sakset fra http://milov.nl/forum/1/461/50
Virker til at være en brugbar løsning, vil i hvert tilfælde lige prøve om det kan lade sig gøre nogenlunde elegant.

There is some terrible advice in this thread.
I had this problem and solved it like this:

1) change the action="" attribute of your <form> tag from action="myform.php" to action="myform.php?add=1". You can still use method="POST" and POST all your other variables.

2) at the top of your php script, you can do a check for:

// ** START SCRIPT ** //

if ($_GET["add"]=="1") {
// .. place your update/insert logic here ..
// redirect to the same page, but without the add=1 variable
header("Location: myform.php")
// stop processing of script after redirect
exit();
}

// normal display of page should go here - this is where the redirect above will redirect to.

// ** END SCRIPT ** //



The way this works is that the form submits to a page with URL of yourpage.php?add=1 - and then it redirects to yourpage.php. The users browser thinks these two are actually different pages, but they are not, and it is very simple to check what stage we are at (submit or normal display) using the logic given above.

Hope that helps.
Avatar billede Peter Praktikant
06. juni 2004 - 22:14 #15
Udover adressebaren af en eller anden mærkelig grund ikke opdateres, det har vel noget at gøre med at der bliver redirectet midt i det hele, ja så virker det fint. Jeg bruger så bare email=true i url i stedet for det skjulte felt i formen.
Avatar billede dennismp Nybegynder
06. juni 2004 - 22:17 #16
Har du prøvet med en anden browser? bare for at se hvordan det virker?
Avatar billede Peter Praktikant
06. juni 2004 - 22:26 #17
Ja, jeg har haft prøvet med opera med samme resultat. Men nu virker det:
www.koeleindustrien.dk under kontakt (der er intet css endnu).
Jeg synes løsningen med at bruge url'en er ganske udemærket, det er meget begrænset hvad man kan lave af ballade ved at ændre i den da der bliver checket for om formen er korrekt udfyldt.
Avatar billede dennismp Nybegynder
06. juni 2004 - 22:31 #18
Det ser da ud til at virke fint :)
Avatar billede Peter Praktikant
08. juni 2004 - 18:35 #19
Nå, så kan vi vist godt afslutte dette spørgsmål, formen virker og er færdig pånær css.
Hvis du ligger et svar får du nogle point.
Avatar billede dennismp Nybegynder
08. juni 2004 - 18:46 #20
ok :)
Avatar billede Peter Praktikant
11. juni 2004 - 14:47 #21
får af en eller anden mærkelig grund ikke alle mails, så så først dit svar nu helt tilfældigt da jeg lige ville tjekke.
Tak for hjælpen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester