开发者

How to stop form from sending email more times after initial success.

Can someone please show me example code or specify what i am doing wrong as solutions below have not yielded much luck for me :(

I am working on a contact form which uses jquery and php to validate and send email respectively. The form works fine until the point after the user successfully submits the form. Once the form has been submitted, a success message is successfully displayed on the same page however, upon referesh the page sends another email, thus if I do countless refreshes, I would get countless mails in my box.

//handler.php
if(isset($_POST['submit'])) {
    if(!isset($hasError)) {
        $body = "Name: $name \n\nEmail: $email \n\nEnquiry: $enquiry";
        $headers = 'From: My Site <'.$emailTo.'>' . "\r\n" . 'Reply-To: ' . $email;

        mail($emailTo, $subject, $body, $headers);
        $emailSent = true;
        header("location: ../about/?action=sent");
        exit();
}   

//index.php
var_dump($_GET);
<?php if(isset($hasError)) { ?> 
    <p class="error">Please make sure you have filled all fields with valid information. Thank you.</p开发者_如何学Go>
<?php } ?>                        
<?php if(isset($emailSent) && $emailSent == true) { ?>
    <p><strong>Your enquiry was sent successfully.</strong></p>
    <p>Thank you for your enquiry! Your email was successfully sent and we will be in touch with you promptly.</p>
<?php }; ?>                       
<form id="contactform" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    <fieldset>
        <legend>Enquiry form</legend>
        <label for="name">Name:</label><input type="text" size="50" name="name" id="name" value="" class="required" />
        <label for="email">Email:</label><input type="text" size="50" name="email" id="email" value="" class="required email" />
        <label for="enquiry">Enquiry:</label><textarea rows="5" cols="20" name="enquiry" id="enquiry" class="required"></textarea>
        <input type="submit" name="submit" value="Submit enquiry" class="curved-btn"></input>
        <input type="hidden" id="form-id" name="form-id" value="general"></input>
    </fieldset>
</form>

Any help would be greatly appreciated :)


You should use the post/redirect/get pattern here.

Using this pattern advocates sending a redirect as a response from your form handling page, and as a result subsequent refreshes will not trigger these actions more than once.

From the documentation:

...instead of returning a web page directly, the POST operation returns a redirection command.

In pseudo-code, your handler page should have something like:

  • Whatever initial handling code you have
  • Send Email
  • header("Location: /someotherpage");
  • exit();


You need to properly redirect after the email is sent. I've been using the following code for years as part of a utility class. Unfortunately it's been copied and re-posted numerous times on the net, so I have no idea who actually created it.

// func: redirect($to,$code=307)
// spec: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
// 301 Moved Permanently - Forget the old page existed
// 302 Found - Use the same method (GET/POST) to request the specified page.
// 303 See Other - Use GET to request the specified page. Use this to redirct after a POST.
// 307 Temporary Redirect - Good for response to POST.
// redirect('/')
// redirect("/my/page")
// redirect("http://www.foo.bar/page.htm",303)
// redirect("./index.php",307)
public function redirect($to,$code=307) {
    $location = null;
    $sn = $_SERVER['SCRIPT_NAME'];
    $cp = dirname($sn);
    if (substr($to,0,4)=='http') $location = $to; // Absolute URL
    else {
        $schema = $_SERVER['SERVER_PORT']=='443'?'https':'http';
        $host = strlen($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:$_SERVER['SERVER_NAME'];
        if (substr($to,0,1)=='/') $location = "$schema://$host$to";
        elseif (substr($to,0,1)=='.') {
            $location = "$schema://$host/";
            $pu = parse_url($to);
            $cd = dirname($_SERVER['SCRIPT_FILENAME']).'/';
            $np = realpath($cd.$pu['path']);
            $np = str_replace($_SERVER['DOCUMENT_ROOT'],'',$np);
            $location.= $np;
            if ((isset($pu['query'])) && (strlen($pu['query'])>0)) $location.= '?'.$pu['query'];
        }
    }

    $hs = headers_sent();
    if ($hs==false) {
        if ($code==301) header("301 Moved Permanently HTTP/1.1"); // Convert to GET
        elseif ($code==302) header("302 Found HTTP/1.1"); // Conform re-POST
        elseif ($code==303) header("303 See Other HTTP/1.1"); // dont cache, always use GET
        elseif ($code==304) header("304 Not Modified HTTP/1.1"); // use cache
        elseif ($code==305) header("305 Use Proxy HTTP/1.1");
        elseif ($code==306) header("306 Not Used HTTP/1.1");
        elseif ($code==307) header("307 Temorary Redirect HTTP/1.1");
        else trigger_error("Unhandled redirect() HTTP Code: $code",E_USER_ERROR);
        header("Location: $location");
        header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
    }
    elseif (($hs==true) || ($code==302) || ($code==303)) {
        // todo: draw some javascript to redirect
        $cover_div_style = 'background-color: #ccc; height: 100%; left: 0px; position: absolute; top: 0px; width: 100%;';
        echo "<div style='$cover_div_style'>\n";
        $link_div_style = 'background-color: #fff; border: 2px solid #f00; left: 0px; margin: 5px; padding: 3px; ';
        $link_div_style.= 'position: absolute; text-align: center; top: 0px; width: 95%; z-index: 99;';
        echo "<div style='$link_div_style'>\n";
        echo "<p>Please See: <a href='$to'>".htmlspecialchars($location)."</a></p>\n";
        echo "</div>\n</div>\n";
    }
    exit(0);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜