I am trying to use fetch()
API POST method in order to grab the POST data in PHP.
Here is what I have tried:
var x = "hello";
fetch(url,{method:'post',body:x}).then(function(response){
return response.json();
});
PHP:
<?php
if(isset($_GET['x']))
{
$get = $_GET['x'];
echo $get;
}
?>
Is this correct?
POST request using fetch API: To do a POST request we need to specify additional parameters with the request such as method, headers, etc. In this example, we'll do a POST request on the same JSONPlaceholder and add a post in the posts. It'll then return the same post content with an ID.
Approach: First make the necessary JavaScript file, HTML file and CSS file. Then store the API URL in a variable (here api_url). Define a async function (here getapi()) and pass api_url in that function. Define a constant response and store the fetched data by await fetch() method.
The fetch() method: Fetch API comes with a fetch () method that allows you to fetch data from all sorts of different places and work with the data fetched. It allows you to make an HTTP request, i.e., either a GET request (for getting data) or POST request (for posting data).
It depends:
If you want to $_GET['x']
, you need to send the data in the querystring:
var url = '/your/url?x=hello';
fetch(url)
.then(function (response) {
return response.text();
})
.then(function (body) {
console.log(body);
});
If you want to $_POST['x']
, you need to send the data as FormData
:
var url = '/your/url';
var formData = new FormData();
formData.append('x', 'hello');
fetch(url, { method: 'POST', body: formData })
.then(function (response) {
return response.text();
})
.then(function (body) {
console.log(body);
});
Apparently, when using the Fetch API to send data to a PHP server, you'll have to handle the request a little different from what you're used to.
The data you're "POSTing" or "GETting" is not going to be available in the super global variables since this input is not coming from a
multipart-data form
or an application/x-www-form-urlencoded
You can get your data by reading the special file: php://input
, for example using file_get_contents('php://input')
and then try to decode that input with json_decode()
.
You can read more about it here:
https://codepen.io/dericksozo/post/fetch-api-json-php
I use the postData function from MDN:
/**
* send_body___receive_response.js
*
* Can of-course be in <script> tags in HTML or PHP
*/
async function postData( url='', data={ } ) {
// *starred options in comments are default values
const response = await fetch(
url,
{
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "same-origin", // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json", // sent request
"Accept": "application/json" // expected data sent back
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify( data ), // body data type must match "Content-Type" header
},
);
return response.json( ); // parses JSON response into native JavaScript objects
}
const data = {
'key1': 'value1',
'key2': 2
};
postData( 'receive_body___send_response.php', JSON.stringify( data ) )
.then( response => {
// Manipulate response here
console.log( "response: ", response ); // JSON data parsed by `data.json()` call
// In this case where I send entire $decoded from PHP you could arbitrarily use this
console.log( "response.data: ", JSON.parse( response.data ) );
} );
You could just POST data but I like to receive a response that it was successful.
/**
* receive_body___send_response.php
*/
/* Get content type */
$contentType = trim($_SERVER["CONTENT_TYPE"] ?? ''); // PHP 8+
// Otherwise:
// $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
/* Send error to Fetch API, if unexpected content type */
if ($contentType !== "application/json")
die(json_encode([
'value' => 0,
'error' => 'Content-Type is not set as "application/json"',
'data' => null,
]));
/* Receive the RAW post data. */
$content = trim(file_get_contents("php://input"));
/* $decoded can be used the same as you would use $_POST in $.ajax */
$decoded = json_decode($content, true);
/* Send error to Fetch API, if JSON is broken */
if(! is_array($decoded))
die(json_encode([
'value' => 0,
'error' => 'Received JSON is improperly formatted',
'data' => null,
]));
/* NOTE: For some reason I had to add the next line as well at times, but it hadn't happen for a while now. Not sure what went on */
// $decoded = json_decode($decoded, true);
/* Do something with received data and include it in response */
// dumb e.g.
$response = $decoded['key2'] + 1; // 3
/* Perhaps database manipulation here? */
// query, etc.
/* Send success to fetch API */
die(json_encode([
'value' => 1,
'error' => null,
'data' => null, // or ?array of data ($response) you wish to send back to JS
]));
Working example that show how to add two numbers with fetch api using FormData.
For each operation you better have different FormData with its own fields.
HTML:
<html>
<head></head>
<body>
<div id="numbers_addition">
<input type="text" id="num1" placeholder="First Number">
<input type="text" id="num2" placeholder="Second Number">
<button type="button" onclick="addMyNumbers()">Add</button>
<p id="result"></p>
</div>
<script id="script_add">
function addMyNumbers()
{
let num1=document.getElementById("num1").value;
let num2=document.getElementById("num2").value;
opAddNumbers(num1, num2);
}
const frmAddNumbers = new FormData(); // create single instance
frmAddNumbers.set('cmd', "add_numbers"); // this cmd will not change
frmAddNumbers.set('first_number', "");
frmAddNumbers.set('second_number', "");
function opAddNumbers(num1, num2) {
frmAddNumbers.set('first_number', num1);
frmAddNumbers.set('second_number', num2);
fetch('./cmd.inc.php', {method: 'POST', body: frmAddNumbers})
.then(res => res.json()) // res.text()
.then(res => displayResult(res))
.catch(e => console.error('Error, opAddNumbers(), ' + e))
}
function displayResult(response)
{
console.log(response);
document.getElementById("result").innerHTML = `Result = ${response["result"]}`;
}
</script>
</body>
</html>
PHP ('cmd.inc.php'):
<?php
$cmd=$_POST['cmd'];
switch ($cmd) {
case "add_numbers":
$num1=$_POST['first_number'];
$num2=$_POST['second_number'];
$result = array("result" => $num1 + $num2);
$output = json_encode($result);
break;
}
echo $output;
If it happens that you need to work with an existent server, that it's coded with $_POST and expect parameters from a normal form, NOT ENCODED AS JSON, you can use the formdata, that's exatctly to simulate a form.
let fd = new FormData();
fd.append("var1", val)
fd.append("var2", "Hello World");
fetch('/servers/server.php', {method: "POST", body: fd})
In this way, your server will receive POSTed fields as they were from a normal form input field.
$var1 = $_POST['var1']; $var2 = $_POST['var2'];
Remember $_POST
in PHP only grabs either formData()
or urlSearchParams()
data and for other all types of data especially data from the importing from other files or external api data, you must follow the steps.
Steps:
file_get_contents(php://input)
to receive the data in phpjson_decode($data)
and finally after reading/writing to the databasejson_encode($response)
.It's Easy :-))
you can build the body "foo=bar&blah=1" from a json { foo: "bar", "blah": 1}
async function json_as_post_data() {
let data = {
foo: "bar",
"blah": 1
}
return fetch('url-here', {
method: 'post',
headers: { "Content-type": "application/x-www-form-urlencoded; charset=UTF-8" },
body: Object.entries(data).map(([k, v]) => { return k + '=' + v }).join('&') // 'foo=bar&blah=1'
}).then(response => {
return response.json();
});
}
console.log(await json_as_post_data());
echo json_encode($_POST);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With