serialize data from AJAX request to PHP - javascript

My problem is very common. I must be doing some silly mistake somewhere but I am not able to figure it out.
I am send my form data in serialized form but it is not coming to PHP at all.
Angular JS code:
saveForm: function() {
var str = $('#feedbackForm').serializeArray();
alert(JSON.stringify(str)); // here I am getting my data properly
return $http({
method :'POST',
url:'http://localhost/api?module=form&app_id=APP001&action=save&formid=2&user_id=3',
data: str
});
}
PHP
$log->info($_REQUEST); // I am getting all GET parameters correctly
tried this also
$log->info($_POST);
it is not printing my data. why?

By default, the $http will send the data as application/json, which won't be recognized by the $_POST in PHP.
You have to choose either sending the data as form data like this:
return $http({
method: 'POST',
url: 'http://localhost/api?module=form&app_id=APP001&action=save&formid=2&user_id=3',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: str
});
Or don't use the $_POST but read and parse input directly in PHP like this:
$rawInput = file_get_contents('php://input');
$data = json_decode($rawInput);
Hope this helps.

Related

fetch does not send post data

I have the following js snippet:
fetch('/some/webhook', {
method: 'post',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({test:'1'})
}).then(function(res) {
// do something here
}).then(function(data) {
// do something else here
});
For hours I am trying to get the body to my server, but the listening script sees nothing in the $_POST variable. The webhook receives the request. A simple:
die (var_dump($_POST));
results in an empty array shown in the console where I would have expected to see the variable test with value 1.
What is wrong?
The way you are sending your data, php will not populate de _POST variable
If you want to send json content, you should do
$data = json_decode(file_get_contents('php://input'), true);
echo $data["test"];
Alternative solution, if you'd rather have your data in _POST you should send a multipart/form-data header and use a new FormData(); as the body of fetch.

Javascript fetch api payload not delivered

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.

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);
});

Read PHP output from array with AJAX

My PHP is outputting data like this:
$data['full_feed'] = $sxml;
$data['other_stuff']= $new;
echo json_encode($data);
So, in my jQuery, I'm doing this.
$.ajax({
url: 'untitled.php',
type: 'GET',
success: function(data) {
console.log(data['full_feed']);
});
This comes back undefined. So does console.log(data.full_feed). I'm getting back from PHP a valid JSON object, but missing how I can "parse" it correctly.
Parse "data" parameter in response with jQuery.parseJSON function. Then use parsed.full_feed value. Like below:
$.ajax({
url: 'untitled.php',
type: 'GET',
success: function(data) {
data = jQuery.parseJSON(data);
console.log(data.full_feed);
});
You can do like #tilz0R said or for your example to work you need to tell the browser you are sending a json response. So need to set content type header like
header('Content-Type: application/json');
echo json_encode($data);
to see what the server is returning do console.log(typeof data). If its a string you need to parse it. if its an object, it is already parsed.
Also you can put dataType:'json' in your ajax call to let jquery know you are excepting a json response.

Posting JSON string to PHP page

Okay, I'm having some suicidal issues posting a JSON string to a PHP page. I have literally been through the top ten results on Google and plenty of SO questions related to my problem, but still can't work out what I'm doing wrong.
I have multiple forms on a page and want to collect all form fields, turn them into a JSON string and post them to a PHP page, where a script iterates each item and updates the relevant database tables.
This is my jQuery/JS script to collect the data from all the forms:
var photo_annotations = {};
$('form').each(function(i) {
var id = $(this).attr('id');
photo_annotations[id] = {
caption: $('#'+id+'_caption').val(),
keywords: $('#'+id+'_keywords').val(),
credit: $('#'+id+'_credit').val(),
credit_url: $('#'+id+'_credit_url').val()
};
});
If I console.log my photo_annotations object, this is what is produced, based on a two form example:
({11:{caption:"Caption for first photo.", keywords:"Keyword1,
Keyword2, Keyword3", credit:"Joe Bloggs",
credit_url:"www.a-domain.com"}, 12:{caption:"Caption for Lady Gaga.",
keywords:"Keyword3, Keyword4", credit:"John Doe",
credit_url:"www.another-domain.com"}})
I then need to POST this as a string/JSON to a PHP page, so I've done this:
$.ajax({
type: 'POST',
dataType: 'html',
url: 'ajax/save-annotations.php',
data: { data: JSON.stringify(photo_annotations) },
contentType: "application/json; charset=utf-8",
success: function(data) {
if (data) {
$('#form_results').html(data);
} else {
alert("No data");
}
}
});
And on my PHP page, I've got this:
<?php
//print_r($_POST['data']);
$decoded = json_decode($_POST['data'],true);
print_r($decoded);
?>
Now, this isn't the only thing I've tried. I've tried to remove all the JSON settings from the AJAX script, in a bid to just send a pure string. I've tried removing contentType and JSON.stringify but still won't go. My PHP page just can't get the data that I'm sending.
Please help push me in the right direction. I've got to the point where I can't remember all the variations I've tried and this little script is now on day 2!
MANAGED TO FIX IT
I rewrote my AJAX function and it worked. I have no idea what was going wrong but decided to test my AJAX function with a very basic data string test=hello world and found that no POST data could be read from the PHP page, even though Firebug says that the page did in fact receive post data matching what I sent. Very strange. Anyway, this is the revised AJAX script:
var the_obj = JSON.stringify(photo_annotations);
var post_data = "annotations="+the_obj;
$.ajax({
url: 'ajax/save-annotations',
type: 'POST',
data: post_data,
dataType: 'html',
success: function(data) {
$('#form_results').html(data);
}
});
Try:
$.ajax({
// ...
data: { data: JSON.stringify(photo_annotations) },
// ...
});
If you just set the "data" property to a string, then jQuery thinks you want to use it as the actual query string, and that clearly won't work when it's a blob of JSON. When you pass jQuery an object, as above, then it'll do the appropriate URL-encoding of the property names and values (your JSON blob) and create the query string for you. You should get a single "data" parameter at the server, and it's value will be the JSON string.
Try urldecode or rawurldecode as follows:
<?php
$decoded = json_decode(urldecode($_POST['data']), true);
print_r($decoded);
?>
I rewrote my AJAX function and it now works. I have no idea what was going wrong but decided to test my AJAX function with a very basic data string test=hello world and found that no POST data could be read from the PHP page, even though Firebug says that the page did in fact receive post data matching what I sent. Very strange. Anyway, this is the revised AJAX script:
var the_obj = JSON.stringify(photo_annotations);
var post_data = "annotations="+the_obj;
$.ajax({
url: 'ajax/save-annotations',
type: 'POST',
data: post_data,
dataType: 'html',
success: function(data) {
$('#form_results').html(data);
}
});
The only thing I can think of is that the order of AJAX settings needed to be in a particular order. This is my old AJAX script which does not send POST data successfully - well it does send, but cannot be read!!
var the_obj = JSON.stringify(photo_annotations);
var data_str = "annotations="+the_obj;
$.ajax({
type: 'POST',
dataType: 'html',
data: data_str,
url: 'ajax/save-annotations.php',
success: function(data) {
$('#form_results').html(data);
}
});
in your ajax call try resetting the dataType to json
dataType: "json",
You wouldn't have to use the JSON.stringify() either. On your php script you won't have to decode [json_decode()] the data from the $_POST variable. The data will be easy readable by your php script.

Categories