每次刷新页面时,PHP联系表单都会发送电子邮件

时间:2017-02-19 12:17:34

标签: php forms email email-attachments contact-form

每次刷新页面时,PHP联系表单都会发送电子邮件。如果用户发送一次消息并再次刷新,则会再次发送相同的消息。每次刷新页面时都会发生这种情况。

以下是我的代码形式:

if (isset($_POST['submit'])) {
    if ($_POST['email'] == '' || $_FILES['file_upload'] == '' || $_POST["fname"] == '' || $_POST["lname"] == '' || $_POST["message"] == '') {
        echo '<p class="red-info">Please Fill All The Fields</p>';

    } else {

        $from_email      = $_POST['email']; //from mail, it is mandatory with some hosts
        $recipient_email = 'myemail@gmail.com'; //recipient email (most cases it is your personal email)

        //Capture POST data from HTML form and Sanitize them,
        $sender_fname   = filter_var($_POST["fname"], FILTER_SANITIZE_STRING); //sender name
        $sender_lname   = filter_var($_POST["fname"], FILTER_SANITIZE_STRING); //sender name
        $sender_phone_1 = filter_var($_POST["phone_1"], FILTER_SANITIZE_STRING); //sender name
        $sender_phone_2 = filter_var($_POST["phone_2"], FILTER_SANITIZE_STRING); //sender name
        $sender_phone_3 = filter_var($_POST["phone_3"], FILTER_SANITIZE_STRING); //sender name
        $sender_phone   = $sender_phone_1 . ' ' . $sender_phone_2 . ' ' . $sender_phone_3; //sender name
        $reply_to_email = filter_var($_POST["email"], FILTER_SANITIZE_STRING); //sender email used in "reply-to" header
        $subject        = 'Contact Form'; //get subject from HTML form
        $message        = filter_var($_POST["message"], FILTER_SANITIZE_STRING); //message

        /* //don't forget to validate empty fields
        if(strlen($sender_name)<1){
        die('Name is too short or empty!');
        }
        */

        //Get uploaded file data
        $file_tmp_name = $_FILES['file_upload']['tmp_name'];
        $file_name     = $_FILES['file_upload']['name'];
        $file_size     = $_FILES['file_upload']['size'];
        $file_type     = $_FILES['file_upload']['type'];
        $file_error    = $_FILES['file_upload']['error'];

        if ($file_error > 0) {
            die('Upload error or No files uploaded');
        }
        //read from the uploaded file & base64_encode content for the mail
        $handle  = fopen($file_tmp_name, "r");
        $content = fread($handle, $file_size);
        fclose($handle);
        $encoded_content = chunk_split(base64_encode($content));

        $boundary = md5("sanwebe");
        //header
        $headers  = "MIME-Version: 1.0\r\n";
        $headers .= "From:" . $from_email . "\r\n";
        $headers .= "Reply-To: " . $reply_to_email . "" . "\r\n";
        $headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";

        //plain text
        $body = "--$boundary\r\n";
        $body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
        $body .= "Content-Transfer-Encoding: base64\r\n\r\n";
        $body .= "<br />First Name:" . $sender_fname;
        $body .= "<br />Last Name:" . $sender_lname;
        $body .= "<br />Phone:" . $sender_phone;
        $body .= "<br />Message:";
        $body .= chunk_split(base64_encode($message));

        //attachment
        $body .= "--$boundary\r\n";
        $body .= "Content-Type: $file_type; name=" . $file_name . "\r\n";
        $body .= "Content-Disposition: attachment; filename=" . $file_name . "\r\n";
        $body .= "Content-Transfer-Encoding: base64\r\n";
        $body .= "X-Attachment-Id: " . rand(1000, 99999) . "\r\n\r\n";
        $body .= $encoded_content;

        $sentMail = mail($recipient_email, $subject, $body, $headers);
        if (isset($sentMail)) //output success or failure messages
            {
            echo '<p class="green-info">Your Email Has Been Submitted!We will contact soon.</p>';
            echo "<script>document.contact.reset();</script>";
            header("location: contect.php");
        } else {
            die('Could not send mail! Please check your PHP mail configuration.');
        }
    }
}

2 个答案:

答案 0 :(得分:1)

$sender_lname = filter_var($_POST["fname"], FILTER_SANITIZE_STRING);应该是$sender_lname = filter_var($_POST["lname"], FILTER_SANITIZE_STRING);

如果您要刷新浏览器,他们往往会缓存最后一个POST请求。系统可能会询问您是否要重新提交表单数据。尝试添加带有令牌哈希值的隐藏字段。

<input type="hidden" name="token" value="someHashValue">

实施会话以将提交的令牌与存储在$_SESSION中的令牌进行比较。

session_start();
session_regenerate_id(); //Used properly, helps deter session fixation;
$_SESSION['token'] = "someHashValue"; //Must be unique for each page load.

使用良好的散列函数来创建令牌。我会避开md5sha1

基本上...

if($_SESSION['token'] === $_POST['token'])
{
    //Good. You want to filter, validate, and check this early on.
    //Whatever you do, just be consistent.
}

另外,请谨慎使用代码中浏览器提供的文件名($file_name = $_FILES['file_upload']['name'];)。大多数人会说找不到使用它的方法,但如果你这样做,你仍然需要以某种方式过滤和验证它。重命名文件可能是合适的。检查文件大小也是个好主意。不要过分依赖文件大小位php.ini。如果文件类型很重要,您甚至可以在接受之前尝试检查该文件。

最后,当你到达那里时,如果你打算使用PHP过滤器功能,最好将filter_input_array()INPUT_POST用于你的POST数据。对于$_FILES超全局,我做了一个单独的例程只是为了验证它(但是,你不能使用filter_input_array())。祝好运!你在路上!

答案 1 :(得分:-1)

每次都会发送表单,因为您没有遵循Web编程的一些优秀做法。

首先,在收到提交表单中的数据后,您应该将用户重定向到新页面,将请求类型更改为CSRF token并阻止下次提交。

接下来就是你应该使用CSRF来防止两种情况:双重提交和app.post('/v1/do', function (req, res) { var options = { method: 'PUT', url:`EXTERNAL_API`... }; request(options, function (error, response, body) { if (error) { return res.status(500).send(error); } res.status(200).send(body); }); }) attacks