Search code examples
phpjqueryajaxcallbackphpmailer

PHPMailer send mail successfully but can't return to $.ajax success section


I use PHPMailer (gmail smtp) to send email from a static website form. The problem is, the email is sent successfully, but I can't get the right response in $.ajax 'success: function(result){}' section, everytime come into 'error: function(err){}' instead.

Web Server: XAMPP (localhost)

Code is like below:

HTML Form:

<div id="contactus-form">
    <form id="contactUs" method="post">
        <p>
            <label for="name">Name:</label>
            <input type="text" id="name" class="formbox" name="name"/>
        </p>
        <p>
            <label for="email">Email:</label>
            <input type="email" id="email" class="formbox" name="email"/>
        </p>
        <p>
            <label for="comments">Comments:</label>
            <textarea name="comments" id="comments" rows="8"></textarea>
        </p>
        <p>
            <button form="contactUs" name="send" id="send" type="submit">Send Message</button>
        </p>
    </form>
</div>

JS:

$('#contactUs').submit(function() {
    var message = $("#comments").val();
    var name = $('#name').val();
    var email = $('#email').val();
    $.ajax({
        url: "PHPMailer/gmail.php", 
        method: "POST",
        data: {
            name: name,
            email: email,
            message: message
        },
        dataType: "json",
        success: function(result) {
            console.log(result);
        },
        error: function(err) {
            console.log(err);
        }
    });
});

PHP:

<?php
header('Content-Type: application/json');
require 'PHPMailerAutoload.php';

//Get data send by ajax
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];

$mail = new PHPMailer;
$mail->isSMTP();
$mail->SMTPDebug = 0;
$mail->Debugoutput = 'html';
$mail->Host = gethostbyname('ssl://yoursmpt.com');
$mail->Port = ***;
$mail->SMTPSecure = 'ssl';
$mail->SMTPAuth = true;
$mail->Username = "youraccount@email.com";
$mail->Password = "yourpassword";

$mail->setFrom("from@email.com", "from name");
$mail->addReplyTo($email, $name);
$mail->addAddress('admin@yourdomail.com', 'Admin'); 
$mail->Subject = 'Message From Website';
$mail->msgHTML('<h4>Name: </h4>'.$name.'<br>'.'<h4>Email: </h4>'.$email.'<br>'.'<h4>Message: </h4>'.$message);
$mail->AltBody = 'This is a plain-text message body';

//send the message, check for errors
if (!$mail->send()) { 
    $result = array('status'=>"error", 'message'=>"Mailer Error: ".$mail->ErrorInfo);//
    echo json_encode($result);
} else {
    $result = array('status'=>"success", 'message'=>"Message sent.");
    echo json_encode($result);
}

I added header('Content-Type: application/json'); for gmail.php as well.

When I click the "SendMessage" button, I got a cancelled request:

request gmail.php

Cancelled request details

And it's working fine locally if I add return false; at the end of submit() function. Anyone could help me to figure out what happened in this case, please? Thank you so much.


Solution

  • The problem is I didn't prevent the default submit function.

    Solution 1: Add return false; at the end of submit function

    $('#contactUs').submit(function() {
        ...
        $.ajax({
            url: "PHPMailer/gmail.php", 
            method: "POST",
            data: {...},
            dataType: "json",
            success: function(result) {
                console.log(result);
            },
            error: function(err) {
                console.log(err);
            }
        });
        return false;
    });
    

    Solution 2: Add event.preventDefault() in submit function

    $('#contactUs').submit(function(e) {
        ...
        e.preventDefault();
        $.ajax({
            url: "PHPMailer/gmail.php", 
            method: "POST",
            data: {...},
            dataType: "json",
            success: function(result) {
                console.log(result);
            },
            error: function(err) {
                console.log(err);
            }
        });
    });
    

    In this case, it has no difference between Solution1 and Solution2. But if you don't want to also prevent the events from propagating (any same event in parent elements), it's better to use event.preventDefault(). Please check https://css-tricks.com/return-false-and-prevent-default/.

    I'll appreciate if anyone can add more explanation for why without prevent default submit will cause $.ajax response error.