Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP

Getting a 400 error when submitting email form from tutorial

Hi all,

I followed the tutorial in this blog post (http://blog.teamtreehouse.com/create-ajax-contact-form) but I keep getting a 400 error response when I click submit. The full mailer.php is

<?php

    // Only process POST reqeusts.
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        // Get the form fields and remove whitespace.
        $name = strip_tags(trim($_POST["name"]));
                $name = str_replace(array("\r","\n"),array(" "," "),$name);
        $email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
        $phone = trim($_POST["phone"]);
        $message = trim($_POST["message"]);

        // Check that data was sent to the mailer.
        if ( empty($name) OR empty($message) OR !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            // Set a 400 (bad request) response code and exit.
            http_response_code(400);
            echo "Oops! There was a problem with your submission. Please complete the form and try again.";
            exit;
        }

        // Set the recipient email address.
        // FIXME: Update this to your desired email address.
        $recipient = "hello@romanpaul.io";

        // Set the email subject.
        $subject = "New contact from $name";

        // Build the email content.
        $email_content = "Name: $name\n";
        $email_content .= "Email: $email\n\n";
        $email_content .= "Message:\n$message\n";

        // Build the email headers.
        $email_headers = "From: $name <$email>";

        // Send the email.
        if (mail($recipient, $subject, $email_content, $email_headers)) {
            // Set a 200 (okay) response code.
            http_response_code(200);
            echo "Thank You! Your message has been sent.";
        } else {
            // Set a 500 (internal server error) response code.
            http_response_code(500);
            echo "Oops! Something went wrong and we couldn't send your message.";
        }

    } else {
        // Not a POST request, set a 403 (forbidden) response code.
        http_response_code(403);
        echo "There was a problem with your submission, please try again.";
    }

?>

I'm even getting the correct error message ("Oops! There was a problem with your submission. Please complete the form and try again.") but I can't figure out why it thinks any of the fields are blank. For the sake of completeness here's my JS:

$(function() {
    // Get the form.
    var form = $('.contactForm');

    // Get the messages div.
    var formMessages = $('.formMessages');

    // TODO: The rest of the code will go here...
});

// Set up an event listener for the contact form.
$(form).submit(function(event) {
    // Stop the browser from submitting the form.
    event.preventDefault();

    // TODO
});

// Serialize the form data.
var formData = $(form).serialize();

// Submit the form using AJAX.
$.ajax({
    type: 'POST',
    url: $(form).attr('action'),
    data: formData
})
.done(function(response) {
    // Make sure that the formMessages div has the 'success' class.
    $(formMessages).removeClass('error');
    $(formMessages).addClass('success');

    // Set the message text.
    $(formMessages).text(response);

    // Clear the form.
    $('#name').val('');
    $('#email').val('');
    $('#phone').val('');
    $('#message').val('');
})
.fail(function(data) {
    // Make sure that the formMessages div has the 'error' class.
    $(formMessages).removeClass('success');
    $(formMessages).addClass('error');

    // Set the message text.
    if (data.responseText !== '') {
        $(formMessages).text(data.responseText);
    } else {
        $(formMessages).text('Oops! An error occured and your message could not be sent.');
    }
});

I only changed the initial IDs used in Matt's version to my own classes. Here's the form:

<div id="contact-wrap">   
            <div id="contact-area">
                <form class="contactForm" method="post" action="mailer.php" name="myForm">

                    <div class="fields">
                        <label for="Name">Name</label>
                        <input class="validate" type="text" name="Name" id="name" placeholder="Your Name" required pattern="^[^0-9]+$"/>
                    </div>

                    <div class="fields">
                        <label for="Email">Email</label>
                        <input class="validate" type="email" name="Email" id="email" placeholder="Your Email" required pattern="^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$"/>
                    </div>

                    <div class="fields">
                        <label for="Phone">Phone</label>
                        <input type="text" name="Phone" id="phone" placeholder="Phone"/>
                    </div>

                    <div class="fields">
                        <label for="Message">Message</label>
                        <textarea name="Message" rows="20" cols="20" id="message" placeholder="How can I help you?" required></textarea>
                    </div>
                        <input onclick="validate()" type="submit" name="submit" value="Submit" class="submit-button"/>

                </form>
            </div>
        </div>
        <div class="formMessages"></div>

Try lowercasing the name attribute values in your form. In the script you're looking for $_POST['name'] but in the html form your sending value="Name". Note the uppercase vs lowercase difference.

Hopefully that helps.

-Ben

Thanks Ben, but no luck with that either unfortunately.

1 Answer

Matt West
Matt West
14,545 Points

Hey Roman!

It looks there might be two issue here. The first is that the JavaScript will throw an error "Can't find variable: form" which will prevent the form being submitted using AJAX. To fix this you need to add everything below // Set up an event listener for the contact form. directly below the // TODO: The rest of the code will go here... comment. (Before the close });)

This will make sure the form submits via AJAX, but the submission still won't be successful.

I tried the form on your website and got a 500 error. This suggests that the failure is at the line which sends the email: mail($recipient, $subject, $email_content, $email_headers). Do you have access to your PHP logs? These will likely provide some more information as to what is going on.

Thanks Matt! I had the JS copied exactly, but it looks like the error was due to the placement of the variables. I placed them outside the function and everything worked error free.

The larger issue was actually with my server. I switched from Nginx to Apache and everything went through fine.