69

I know that with the new Fetch API (used here with ES2017's async/await) you can make a GET request like this:

async getData() {
    try {
        let response = await fetch('https://example.com/api');
        let responseJson = await response.json();
        console.log(responseJson);
    } catch(error) {
        console.error(error);
    }
}

But how do you make a POST request?

Rob
  • 6,758
  • 4
  • 46
  • 51

7 Answers7

146

Long story short, Fetch also allows you to pass an object for a more personalized request:

fetch("http://example.com/api/endpoint/", {
  method: "post",
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },

  //make sure to serialize your JSON body
  body: JSON.stringify({
    name: myName,
    password: myPassword
  })
})
.then( (response) => { 
   //do something awesome that makes the world a better place
});

Check out the fetch documentation for even more goodies and gotchas:

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Please note that since you're doing an async try/catch pattern, you'll just omit the then() function in my example ;)

hellojebus
  • 3,267
  • 1
  • 21
  • 23
  • 8
    Why JSON.stringify ? How to send simple form data ?! – Vincent Decaux Aug 08 '18 at 17:26
  • 1
    This is just an example of POST'ing an object. To POST data from a form with many inputs, I would recommend looking into ways to serialize form data into a string. If using jQuery, this can be done using the `$.serialize()` method. If using plain JS, take a look at this thread: https://stackoverflow.com/questions/11661187/form-serialize-javascript-no-framework – hellojebus Aug 08 '18 at 18:28
  • Overall though the ideal is the same, you'll probably convert your form data into an object and serialize using `JSON.serialize()` – hellojebus Aug 08 '18 at 18:30
  • 1
    That did the trick for me, thank you. I replaced Axios for Fetch API and all my POST requests are successful now. It is sad I can't use Axios properly. – Felipe Wagner Jul 08 '20 at 22:02
  • Upvote for the comment "do something awesome that makes the world a better place" – Luffy D. Monkey Aug 10 '23 at 21:10
31

if you want to make a simple post request without sending data as JSON.

fetch("/url-to-post",
{
    method: "POST",

    // whatever data you want to post with a key-value pair

    body: "name=manas&age=20",
    headers: 
    {
        "Content-Type": "application/x-www-form-urlencoded"
    }

}).then((response) => 
{ 
    // do something awesome that makes the world a better place
});
artfulhacker
  • 4,823
  • 1
  • 37
  • 31
manas
  • 6,119
  • 10
  • 45
  • 56
  • Found this while freshening up on fetch. Works perfectly to get general posts without additional backend handling of php input stream. – spyke01 Sep 07 '18 at 15:11
13

How to POST form data to a PHP script

The best way is utilizing the Fetch API and the FormData interface. Here is an example:

function postData() {
  const form = document.getElementById('form');
  const data = new FormData();
  data.append('name', form.name.value);

  try {
    const res = fetch('../php/contact.php', {
      method: 'POST',
      headers: {
        "content-type": "multipart/form-data"
      },
      body: data,
    });

    if (!res.ok) console.log(`POST failed with ${res.status}.`);
  } catch(err) {
    console.error(err);
  }
}
<form id="form" action="javascript:postData()">
  <input id="name" name="name" placeholder="Name" type="text" required>
  <input type="submit" value="Submit">
</form>

Here is a very basic example of a PHP-script that takes the data and sends an email:

<?php
    header('Content-type: text/html; charset=utf-8');

    if (isset($_POST['name'])) {
        $name = $_POST['name'];
    }

    $to = "test@example.com";
    $subject = "New name submitted";
    $body = "You received the following name: $name";
    
    mail($to, $subject, $body);
leonheess
  • 16,068
  • 14
  • 77
  • 112
  • 2
    Actually, only this works with PHP. Neither serializing a key-value object, nor key-value query string doesn't work with fetch. – Michael Zelensky Jan 11 '21 at 20:04
  • 1
    I think that FormData is the right way to send the data. It will work the same as using a form submit. – jcubic Aug 18 '21 at 16:07
9

2021 answer: just in case you land here looking for how to make GET and POST Fetch api requests using async/await or promises as compared to axios.

I'm using jsonplaceholder fake API to demonstrate:

Fetch api GET request using async/await:

         const asyncGetCall = async () => {
            try {
                const response = await fetch('https://jsonplaceholder.typicode.com/posts');
                 const data = await response.json();
                // enter you logic when the fetch is successful
                 console.log(data);
               } catch(error) {
            // enter your logic for when there is an error (ex. error toast)
                  console.log(error)
                 } 
            }


          asyncGetCall()

Fetch api POST request using async/await:

    const asyncPostCall = async () => {
            try {
                const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
                 method: 'POST',
                 headers: {
                   'Content-Type': 'application/json'
                   },
                   body: JSON.stringify({
             // your expected POST request payload goes here
                     title: "My post title",
                     body: "My post content."
                    })
                 });
                 const data = await response.json();
              // enter you logic when the fetch is successful
                 console.log(data);
               } catch(error) {
             // enter your logic for when there is an error (ex. error toast)

                  console.log(error)
                 } 
            }

asyncPostCall()

GET request using Promises:

  fetch('https://jsonplaceholder.typicode.com/posts')
  .then(res => res.json())
  .then(data => {
   // enter you logic when the fetch is successful
    console.log(data)
  })
  .catch(error => {
    // enter your logic for when there is an error (ex. error toast)
   console.log(error)
  })

POST request using Promises:

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
   body: JSON.stringify({
     // your expected POST request payload goes here
      title: "My post title",
      body: "My post content."
      })
})
  .then(res => res.json())
  .then(data => {
   // enter you logic when the fetch is successful
    console.log(data)
  })
  .catch(error => {
  // enter your logic for when there is an error (ex. error toast)
   console.log(error)
  })  

GET request using Axios:

        const axiosGetCall = async () => {
            try {
              const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
    // enter you logic when the fetch is successful
              console.log(`data: `, data)
           
            } catch (error) {
    // enter your logic for when there is an error (ex. error toast)
              console.log(`error: `, error)
            }
          }
    
    axiosGetCall()

POST request using Axios:

const axiosPostCall = async () => {
    try {
      const { data } = await axios.post('https://jsonplaceholder.typicode.com/posts',  {
      // your expected POST request payload goes here
      title: "My post title",
      body: "My post content."
      })
   // enter you logic when the fetch is successful
      console.log(`data: `, data)
   
    } catch (error) {
  // enter your logic for when there is an error (ex. error toast)
      console.log(`error: `, error)
    }
  }


axiosPostCall()
Tellisense
  • 1,858
  • 12
  • 11
4

Here is a solution for a POST request using node-fetch, with async/await.

async function post(data) {
    try {
        // Create request to api service
        const req = await fetch('http://127.0.0.1/api', {
            method: 'POST',
            headers: { 'Content-Type':'application/json' },
            
            // format the data
            body: JSON.stringify({
                id: data.id,
                foo: data.foo,
                bar: data.bar
            }),
        });
        
        const res = await req.json();

        // Log success message
        console.log(res);                
    } catch(err) {
        console.error(`ERROR: ${err}`);
    }
}

// Call your function
post() // with your parameter of Course
sonique
  • 4,539
  • 2
  • 30
  • 39
Tanner
  • 720
  • 1
  • 8
  • 17
1

Here is a complete example: After spending hours tinkering with incomplete code snippets I finally managed to post some json from javascript, pick it up using php on a server, added a data field and finally updated the original web page. Here is the HTML, the PHP and the JS. My thanks to everyone who posted the original code fragments collected here. Similar code is on-line here: https://www.nbest.co.uk/Fetch/index.php

<!DOCTYPE HTML>
<!-- Save this to index.php and view this page in your browser -->
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Javascript Fetch Example</title>
</head>

<body>
<h1>Javascript Fetch Example</h1>
<p>Save this to index.php and view this page in your browser.</p>

<button type="button" onclick="myButtonClick()">Press Me</button>

<p id="before">This is the JSON before the fetch.</p>
<p id="after">This is the JSON after the fetch.</p>

<script src="fetch.js"></script>

</body>
</html>
<!-- --------------------------------------------------------- -->

// Save this as fetch.js --------------------------------------------------------------------------

function success(json) {
  document.getElementById('after').innerHTML = "AFTER: " + JSON.stringify(json);
  console.log("AFTER: " + JSON.stringify(json));
} // ----------------------------------------------------------------------------------------------

function failure(error) {
  document.getElementById('after').innerHTML = "ERROR: " + error;
  console.log("ERROR: " + error);
} // ----------------------------------------------------------------------------------------------

function myButtonClick() {
  var url    = 'json.php';
  var before = {foo: 'Hello World!'};

  document.getElementById('before').innerHTML = "BEFORE: " + JSON.stringify(before);
  console.log("BEFORE: " + JSON.stringify(before));

  fetch(url, {
    method: 'POST', 
    body: JSON.stringify(before),
    headers:{
      'Content-Type': 'application/json'
    }
  }).then(res => res.json())
  .then(response => success(response))
  .catch(error => failure(error));
} // ----------------------------------------------------------------------------------------------

<?php
  // Save this to json.php ---------------------------------------
  $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';

  if ($contentType === "application/json") {
    $content = trim(file_get_contents("php://input"));

    $decoded = json_decode($content, true);

    $decoded['bar'] = "Hello World AGAIN!";    // Add some data to be returned.

    $reply = json_encode($decoded);
  }  

  header("Content-Type: application/json; charset=UTF-8");
  echo $reply;
  // -------------------------------------------------------------
?>
1

In this article, I described about the Second Parameter of fetch().

For submit JSON data

const user =  { name:  'Sabesan', surname:  'Sathananthan'  };
const response = await fetch('/article/fetch/post/user', {
  method: 'POST',
  headers: {
   'Content-Type': 'application/json;charset=utf-8'
  }, 
  body: JSON.stringify(user) 
});

For submit form

const form = document.querySelector('form');

const response = await fetch('/users', {
  method: 'POST',
  body: new FormData(form)
})

For file upload

const input = document.querySelector('input[type="file"]');

const data = new FormData();
data.append('file', input.files[0]);
data.append('user', 'foo');

fetch('/avatars', {
  method: 'POST',
  body: data
});
Sabesan
  • 654
  • 1
  • 10
  • 17