londongrammar
londongrammar

Reputation: 163

Mailing form data with Fetch API

I'm trying to use Fetch API to retrieve data from form and mail it, but the email I'm receiving is empty. The response seems to be successful, but no data being sent. What am I doing wrong?

This is my JS code and my php/html snippet if it's relevant

(function() {

  const submitBtn = document.querySelector('#submit');

  submitBtn.addEventListener('click', postData);

  function postData(e) {
    e.preventDefault();

    const first_name = document.querySelector('#name').value;
    const email = document.querySelector('#email').value;
    const message = document.querySelector('#msg').value;

    fetch('process.php', {
        method: 'POST',
        body: JSON.stringify({first_name:first_name, email:email, message:message})
    }).then(function (response) {
      console.log(response);
      return response.json();
    }).then(function(data) {
      console.log(data);
      // Success
    });

  }

})();



<!-- begin snippet: js hide: false console: true babel: false -->
<?php 
    $to = "[email protected]"; 
    $first_name = $_POST['first_name'];
    $from = $_POST['email']; 
    $message = $_POST['message'];
    $subject = "Test Email";
    $message = $first_name . " sent a message:" . "\n\n" . $message;
    $headers = "From:" . $from;
    mail($to,$subject,$message,$headers);
?>


<form action="" method="post" class="contact__form form" id="contact-form">
  <input type="text" class="form__input" placeholder="Your Name" id="name" name="first_name" required="">
  <input type="email" class="form__input" placeholder="Email address" id="email" name="email" required="">
  <textarea id="msg" placeholder="Message" class="form__textarea" name="message"/></textarea>
  <input class="btn" type="submit" name="submit" value="Send" id="submit"/>
</form>

Upvotes: 0

Views: 6757

Answers (1)

Patrick Evans
Patrick Evans

Reputation: 42746

PHP does not understand JSON request bodies. So when JSON text is sent to it, PHP will not automatically parse the JSON and put the data into the global $_POST variable.

Also fetch() will use the default mime text/plain for content-type when the body is just text. So even if you set body to the data in say the format of x-www-form-urlencoded it will not set the request header to the correct one and PHP won't parse it correctly.

You either have to manually get the sent data and parse it yourself:

<?php

$dataString = file_get_contents('php://input');
$data = json_decode($dataString);
echo $data->first_name;

Send the data as a different content type, ie application/x-www-form-urlencoded by explicitly setting the content-type header and passing the correct formatted body:

fetch('/', {
  method: 'POST',
  headers:{
    "content-type":"application/x-www-form-urlencoded"
  },
  body: "first_name=name&[email protected]"
})

Or even create a FormData object and let fetch automatically detect the correct content-type to use:

var data = new FormData();
data.append('first_name','name');
data.append('email','[email protected]');

fetch('/', {
  method: 'POST',
  body: data
})

Upvotes: 8

Related Questions