Search code examples
phpbootstrap-4ajaxform

$_POST variable is empty on ajax submission of a bootstrap contact form


I know questions like this have been asked before, but none of them have helped me solve this problem. If it is something stupid I have overlooked then I apologize in advance. I have set up a contact form in a bootstrap modal. The html for the form is below:

<div class="modal-body">
    <form id="contactForm" action="contact.php" method="post">
        <div class='form-group'>
            <label class='sr-only' for="name" sr-only="Name">Name</label>
            <input id="name" type="text" name="name" class="form-control" placeholder="Name">
        </div>
        <div class='form-group'>
            <label class='sr-only' for="email" sr-only="Email address">Email</label>
            <input id="email" type="email" name="email" class="form-control" placeholder="Email address">
        </div>
        <div class='form-group'>
            <label class='sr-only' for="message" sr-only="Your Message"></label>
            <textarea id="message" type="text" name="message" rows='6' class="form-control" placeholder='Type your message here...'></textarea>
        </div>
        <br>
        <div class="form-group">
            <label class="control-label" for="human" sr-only="Prove you're human.  What is 3 + 2?">Prove you're human:  3 + 2 = ?</label>
            <input type="text" class="form-control" id="human" name="human" placeholder="Type the number here">
        </div>
        <br>
        <button id='contactFormSubmit' type='submit' name='submit' class='form-control btn btn-block btn-lg btn-info'>
            <i class='fa fa-send'></i>&nbsp;&nbsp;Send Message
        </button>
    </form>
</div>

Below is the ajax request. Note that there is some form validation; the ajax is about half way down the code:

$('form#contactForm').submit(function(e) {
    e.preventDefault();
    $('input.borderRed, textarea.borderRed').removeClass('borderRed');
    var name = $('#name');
    var email = $('#email');
    var message = $('#message');
    var human = $('#human');
    var vals = [name, email, message, human];
    var emptyVals = [];
    for(var i=0; i < vals.length; i++) {
        if (vals[i].val() == '') {
            vals[i].addClass('borderRed');
            emptyVals.push(vals[i]);
        }
    }
    if (emptyVals.length > 0) {
        $('#intro').append('<div class="alert alert-danger alert-dismissable fade show"><strong>Please fill in all fields to send a message.</strong><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
        return false;
    } else if(human.val() != 5) {
        $('#intro').append('<div class="alert alert-danger alert-dismissible fade show"> <strong>Try that math problem again!</strong><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
        human.addClass('borderRed');
        return false;
    } else {
        $.ajax({
            data: $(this).serialize(),
            type: "POST",
            url: "contact.php", 
            success:function(response) {
                if (response == 'success') {
                    $('#intro').append('<div class="alert alert-success alert-dismissible fade show"> <strong>Your message was sent successfully.</strong><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
                    $('.borderRed').removeClass('borderRed');
                } else {
                    $('#intro').append('<div class="alert alert-danger alert-dismissible fade show"> <strong>There was a problem with your submission.  Please try again.</strong><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
                }
            }
        });
    }
});

Finally, here is contact.php. Note that this is incomplete. At this point I am trying to confirm that I am getting $_POST data:

<?php
if( empty($_POST )) {
    echo "Post is empty.";
} elseif( !empty($_POST)) {
    echo "Post is not empty.";
}

print_r($_POST);

$to = '';
$subject = 'Contact Form Submission';
$header = "From: ".$name." <".$email.">";

$name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
$message = filter_var($_POST['message'], FILTER_SANITIZE_STRING);
$message = wordwrap($message, 70);

$response = '';

if ($name && $email && $message) {
    $response = 'success';
    mail($to, $subject, $header, $message);
} else {
    $response = 'error';
}

echo $response;
?>

As the title of my question suggests, I am not getting the data. At contact.php I am getting the empty post message, and for print_r($_POST), I get Array (). The post data is not arriving, and I cannot figure out why.

EDIT: I should have mentioned that if I console.log($(this).serialize()); just before the ajax call, then I get the correct serialized data in the console window. So the data is there and ready to go just before the ajax call.


Solution

  • opening a browser window and pointing it at localhost/mysite/contact.php. That's where the "Post is empty" message is echoed and where I get the "Array ()" output from my print_r($_POST)

    So this is what you are doing:

    1. Making a GET request to an HTML document by opening it in the browser window
    2. Letting JavaScript in the HTML document make a POST request to contact.php
    3. Not examining the response to that POST request
    4. Making a GET request to contact.php by opening it in the browser window
    5. Looking at the response to that GET request

    Making a GET request to a URL you previously made a POST request to does not show you the response you got to that POST request.

    You have two different requests and two different responses.

    If you want to see the response to the request you triggered using Ajax then you have to look at that response. You can do this by examining the response variable in your success function or by looking at the Network tab of your browser's developer tools.