Javascript fetch api payload not delivered - javascript

console.log("data ", data); // returns an object in JSON format {propertyName: propertyValue}
dataString = JSON.stringify(dataString); //correctly stringified json
let response = await fetch('updateRecevingEntry.php',
{
method:'POST',
headers: {'Content-Type':'application/json'},
body: dataString
}).then(response=>response.json());
however I get back an undefined index on the php side.
where the php is:
$matkey = $_POST['materialKey'];
returns
<b>Notice</b>: Undefined index: materialKey in <b>path/updateRecevingEntry.php</b> on line <b>3</b><br />
for all the data... none of it is getting caught.
so why is the _POST['propertyName'] not catching the stringData from the body?
I've tried a few variations, such as sending the data instead of the string data messing with the header, but I can't seem to figure out how to send the payload such that _POST['propertyName'] catches the data in the body.
I was using $.ajax from jquery before, and it was working: but I'm in the process of refactoring that out.
the Fetch api is new to me. where am I going wrong. I also don't want to parse a json object on the php side.
after reading one of the answers, I got it to work in one case,
but
let response = await fetch('updateRecevingEntry.php',
{
method:'POST',
headers: {'Content-Type':'application/json'},
body: sendData
}).then(response=>response.json());
and the php
$postData = json_decode(file_get_contents("php://input"), true);
var_dump($postData);
just returns a big fat NULL.
Edit two: turns out it just needs to actually be encoded via JSON.stringify(sendData). Since the. It works as expected.

The first thing I've noticed is that you're not using the right variable (you're using stringData instead of dataString):
dataString = JSON.stringify(dataString); //correctly stringified json
let response = await fetch('updateRecevingEntry.php', {
method:'POST',
headers: {'Content-Type':'application/json'},
body: dataString
}).then(response=>response.json());
Though you shouldn't need to stringify it as you're sending it with json headers.
Additionally, have you tried instead of $_POST, using php://input?
From PHP.net:
php://input is a read-only stream that allows you to read raw data from the request body. In the case of POST requests, it is preferable to use php://input instead of $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives. Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by default, it is a potentially less memory intensive alternative to activating always_populate_raw_post_data. php://input is not available with enctype="multipart/form-data".
So you would use it like so:
$postData = json_decode(file_get_contents("php://input"), true);
$matkey = $postData['materialKey'];
This reads the body of the POST request as a JSON string then converts it to a PHP array.

Related

Not able to access Ajax post response Object properties

I'm trying to fetch some data using POST method. The URL is sending proper response, which is of course an Object. When I try to access the responseJSON which is a property of the response Object, it returns undefined. But when try to do the same thing on console, it works fine! objectName.responseJSON works properly in this case. But why it's not working the same way while I use it in my code?
Also, on a button click, which changes a little bit of the fetched data, it again works fine. Means... that response Object and it's properties work fine on a button click but on $(document).ready or $(document).load. Why this is happening?
//Fetching data from URL
oldData = $.post("{$_url}reports/get_all_transactions", {
'startDate': document.getElementById('startDate').value,
'endDate': document.getElementById('endDate').value
});
//Printing the result on Console
$(document).ready(function() {
console.log(oldData); //This prints the whole response object
console.log(oldData.responseJSON); //This outputs 'undefined'
})
I even tried JSON.parse(), JSON.stringify() and their combination on the object. But on Stringify, it's just converting the first property of the object into String and not the whole object. And the Parse method returns error.
Then how can I access my desired object property?
Better to use native fetch instead, no need for jQuery these days.
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
startDate : document.getElementById('startDate').value,
endDate : document.getElementById('endDate').value
})
});
const text = await response.text();
const obj = JSON.parse(text)
Docs: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

How to handle json object that was stringified in Python

I have a question about JSON.stringify() and how to parse it. I have a frontend code and a backend in python (Django).
My fetch function looks like this in frontend.
const response = await fetch('some-url', {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
payload: payload
})
});
When i do console.log on JSON.stringify({payload: payload}), its type is string. Then in my backend code, when i print out request.data['payload']), its type is <class 'dict'>. I am confused why the type changed when i sent the request to the backed. I was going to use json.loads() to parse the payload but since it is already dictionary it returns an error and i can just do request.data['payload'] to access its data.
Can someone explain this behavior?
So I guess you are using Django Rest framework.
request.data
Will in Django Rest provide you with a parsed version of the request body. Because you are using the content-type: json it will try and parse it as .. json.
See docs here: https://www.django-rest-framework.org/api-guide/requests/#data
In regular Django for parsing a JSON request it would require the use of json.loads like:
parsed_json = json.loads(request.body)

Post Content-Type undefined and application/json at the same time

I am trying to upload file and post some data at the same time. The value of topicSelected is java script object array. When I check in the c# controller the value of topicSelected is null. When I check the value in my service everything is OK. I am thinking that the problem is that I am not specifying the application/json type.
setNewVideoRecord = function(file, videoName, videoVersion, topicSelected) {
console.log(topicSelected);
var self = this;
var formData = new FormData();
formData.append('file', file);
formData.append('videoName', videoName);
formData.append('videoVersion', videoVersion);
formData.append('topicSelected', topicSelected);
$http.post(self.baseUrl + "Admin/uploadVideoFile", formData, {
withCredentials: true,
headers: {
'Content-Type': undefined
},
transformRequest: angular.identity
}).then(function onSuccess(response) {
self.fileNameUpload = null;
})
}
You don't have an undefined content type. Telling your library that Content-Type is undefined just stops it trying to set its own default and let the underlying XMLHttpRequest object figure it out for itself. Since you are passing it a FormData object, it will examine that to identify the correct content-type (which is be multipart/mixed).
This will encode each piece of data (including the file you are uploading) as a separate part, each of which will have its own content-type set automatically.
You can't make XHR encode the non-file data as JSON. It will use the standard multipart format with a separate part for each of the non-file inputs (and another part for the file).
You need to write the server side code to expect that format and not JSON.
Since topicSelected is a complex data structure (and not a string) you can run it through JSON.stringify() before appending it to the form data object.
Once you read the topicSelected string, you can parse it from JSON on the server.

axios http always returns with empty data

I asked this question before and wasn't able to get an answer. I was able to do use method: 'get' like below to get it working so it was okay but this time I need to use post. In a different project (using react, redux, php, webpack, xampp) the same issue has resurfaced and I am trying to figure it out. So here it is:
register.php
echo $_GET['task'];
index.js
const values = {task: 'doSomething', username: 'username'}
axios({
url: "./server/register.php",
timeout: 20000,
method: 'get',
params: values
}).then(function(response){console.log(response.data)})
When I do the above everything is okay and the data is logged out as 'doSomething'. However, when I try using axios({method: 'POST'}) and changing the php to $_POST['task'] I get an error saying that $_POST['task'] is undefined like below:
index.js
axios({
url: "/projects/myProject/server/register.php",
method: 'post',
data: values
}).then(function(response){console.log(response.data)})
register.php
echo $_POST['task'];
Notice: Undefined index: task
Also when I try this using axios.post() I encounter the exact same problem. I want to use a post request here. Can anyone shed some light on this for me?
Okay after a fair amount of scratching my head I have found an answer. On the PHP this line has to be added before I can access any POST data:
$_POST = json_decode(file_get_contents('php://input'), true);
echo $_POST['task'];
From my understanding the data being inputted from axios is JSON so we must return it in a JSON encoded string using file_get_contents() and then convert this into a php variable from the JSON encoded string using json_decode. Hope this helps someone else. Thank you.
You url has a bad format: it is a path not an url. You have to use either a relative (/register.php) or a absolute (http://localhost/register.php) url depends on how you serve this file with your web server.
As an alternative, on the client side you may massage the data in the JavaScript before POSTing it, eliminating the need to edit the POST data on the server side:
var formatAxiosPostData = function (obj) {
// Create formData object:
var formDataObject = new FormData();
// This step necessary when the obj contains additional overhead data,
// such as what's created on a 'this.$data' Vue.js object:
obj = JSON.parse(JSON.stringify(obj));
// Fill formData object with the key-value pairs:
Object.keys(obj).forEach(function (key) {
formDataObject.append(key, obj[key]);
});
return formDataObject;
};
// example usage:
axios({
url: "/projects/myProject/server/register.php",
method: 'post',
data: formatAxiosPostData(values)
}).then(function (response){
console.log(response.data);
});

Ajax post response coming back successfully - can't log/print to screen

I'm successfully posting data to the server via $.post(). When I attempt to do anything with the response, I get nothing. No console log. Can't replace text or HTML with the data. Nothing.
Here's the post:
$.post(myUrl, {myVar: myVar}, function(data) {
console.log(data);
});
And here's the response:
It may not be able to "guess" the data type as the default 4th parameter not set implies. set dataType parameter
$.post(myUrl, {myVar: myVar}, function(data) {
console.log(data);
}, 'text');
Also be sure that it returns a 200 OK response from the server or else success won't run.
You need to modify the response (probably) into a JSON format so that you can catch it. PHP's header for JSON is:
header("Content-Type: application/json"); //Set header for outputing the JSON information
You will need to include that in your PHP file that you are sending a request to. You may also need to specify the headers content in the post request, as I mainly use Angular, I'm a bit unsure of what the AJAX header for this case, but try something like:
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }

Categories