4

As far as MDN says, the right way to do a POST request with fetch and sending data is: (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)

var url = 'https://example.com/profile';
var data = {username: 'example'};

fetch(url, {
  method: 'POST', // or 'PUT'
  body: JSON.stringify(data), // data can be `string` or {object}!
  headers:{
    'Content-Type': 'application/json'
  }
}).then(res => res.json())
.then(response => console.log('Success:', JSON.stringify(response)))
.catch(error => console.error('Error:', error));

but I spent 2 days trying to make it work (Chrome, Firefox, Edge) but I couldn't... the problem is that body isn't sent to server (GET request works ok), is not server problem, (I'm using PHP 7 on same machine), I debugged the request and no body content at all was sent to server...

At last, and with the help of two friends, we realized than using other header and other body format, body was sent. These are my test files that work:

<body>
<button onclick='buttonOneClick()'>One (GET)</button>
<button onclick='buttonTwoClick()'>Two (POST)</button>
<script>
function buttonOneClick(){
    fetch('server.php?text=one&id=1')
        .then(r => r.text())
        .then(res => alert('you sent '+res));
} 
function buttonTwoClick(){

    let data = "text=two&id=1";
    fetch('server.php', {
        method: 'POST',
        body: data,
        headers: {
            'Content-Type':'application/x-www-form-urlencoded',
        },
    })
    .then(r => r.text())
    .then(res => alert('you sent '+res));
}
</script>
</body>

and server file, in PHP:

<?php
$param = $_REQUEST['text'] ?? "nothing";
print $param;

I had to use an "application/x-www-form-urlencoded" instead of "application/json" Content type header and using a string for "body" property.

This is the ONLY way "body" is sent in a fetch POST request... And yes, when I was using "application/json" header and JSON.stringify for body, I tried using a lot of properties, such as "mode", "cache", "credentials"... and "POST" and/or "Content-Type" in lowercase... and simple and double quotes in json data... but nothing worked

  • It definitely works look at the request in your developer tools network tab... millions of people use it. The issue must be in your server. – Dominic Oct 15 '18 at 10:20

2 Answers2

2

JSON body isn't the $_POST like usual data in PHP afaik. You should be able to use this snippet to read the json though.

// Get JSON as a string
$json_str = file_get_contents('php://input');
// Get as an object
$json_obj = json_decode($json_str);
  • Thank you, it works but my first reaction was: WTF??? Really??? I can't find any reason to migrate my ajax calls to "fetch" since I have to use this kind of "dirty" trick and I have to change PHP scripts too... I have patched my php script with this: $json_str=file_get_contents('php://input'); $json_obj=json_decode($json_str,true); $_REQUEST=array_merge($_REQUEST,$json_obj??array()); so I can use scripts as usual (even using GET or POST), but I think it is totally unsense doing that just to use "fetch", having XMLHttpRequest object, which is easier to use and I get same results – José María Ferri Azorín Oct 15 '18 at 13:23
  • Not sure why this hasn't gotten more upvotes. After searching for hours and troubleshooting, this is exactly what was wrong. My brain hurts from how excessive this is just to do what was available before. Thank you so much for supplying this answer – TGammage Mar 01 '22 at 02:15
0

That is because the API is accepting the data with application/x-www-form-urlencoded and verifying if its sent in that format. So the header should be in application/x-www-form-urlencoded. If you are writing the API change the API so that it accepts application/json only then it will give you the result you are looking for.

Shweta Valunj
  • 148
  • 1
  • 11