Passing XMLHttpRequest to PHP results in empty $POST - javascript

So far, I have been working on some code, and have been troubleshooting for awhile and I'm pretty sure my syntax is correct. I've been having to work around a broken testing environment so I can't use normal breakpoints to test this on the backend.
I have the following function in javascript:
function ns_submit_form_inpage(path, data){
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
alert("Message Sent");
}
}
request.open('POST', path, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
var temp_string = array_to_string(data);
alert("data:"+ temp_string);
request.send(data);
}
And the following code in PHP:
<?php
mail("my_email#example.com", "Array: ". print_r($_POST, true), "From:test#example.com");
?>
I call the function, pass my path in along with an array. I get an email and a proper alert, so I know my function is called and the right file is hit and fires. A also know that right before I send off the data, they data is properly in the keyed array (e.g. first_name::bob, last_name::doe). However, the email I receive reads "Array: Array()" and confirmation via my "Message Sent" alert.
I've narrowed down where I think my error could be, and I'm done to pretty much nothing left, it feels like the array is just disappearing into the ether of the internet.

I found my issue. As mentioned, I was sending the data as an array. Although PHP reads the accepted data as an array, and I'm sending an array, the method by which the array is sent (application/x-www-form-urlencoded) doesn't USE an array. It uses a string. So, I had to change the array into a string following the format of "first_name=bob&last_name=doe&foo=bar". Now it works.

Related

How do I make an AJAX POST request with parameters to a PHP backend?

This is an update to a previous question marked as a duplicate (How do I send an AJAX POST request with parameters to PHP?)
I am sending an AJAX request to a PHP backend.
The Javascript functions to make and receive the request:
var httpRequest;
function makeRequest(){
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = receiveResponse;
httpRequest.open("POST", "ajax_handler.php", true);
httpRequest.setRequestHeader('Content-Type', 'application/json');
httpRequest.send(JSON.stringify({key:"value"}));
}
function receiveResponse() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
console.log(httpRequest.responseText);
}
}
}
The PHP backend ajax_handler.php to process the request:
<?php
$data = file_get_contents('php://input');
echo $data;
?>
My original post was marked as a duplicate of this question. That page has no clear examples, though I was able to infer that I should use file_get_contents('php://input') instead of $_POST in the PHP backend, as shown.
Using the code shown, console.log(httpRequest.responseText) in the receiving function logs {"key":"value"} to the console. If I try to interpret this as an array in the PHP backend, however, with
<?php
$data = file_get_contents('php://input');
echo $data["key"];
?>
the response logs { to the console instead of the expected value.
In addition to the use of 'php://input', several responses in the linked duplicate also use the json_decode() function in the PHP backend.
If I include this function in the backend, however, as
<?php
$data = json_decode(file_get_contents('php://input'));
echo $data;
?>
The entire AJAX call breaks. It was set to trigger on a window click, but after including json_decode(), nothing happens on a window click, nothing is returned from the call, and nothing is logged to the console.
Without an example, it's hard for me to tell if I'm doing the AJAX cycle wrong, or if there's a different problem somewhere else in my code. So please, for the love of all that is holy, will someone please post or link me to a self-contained example showing how to make, process, and receive an AJAX call with parameters to a PHP backend? It's incomprehensible that this doesn't already exists somewhere on the internet, but I've been searching and asking for days, and I can't find a single example anywhere. This is without jQuery.
Thank you in advance.
Create an mcve and debug this piece by piece.
<?php
$data = json_decode('{ "test": 123 }');
echo $data;
Will output:
Recoverable fatal error: Object of class stdClass could not be converted to string in /...../test.php on line 4
You've got an object representing the data decoded from JSON. You need to echo a useful part of it. e.g.
<?php
$data = json_decode('{ "test": 123 }');
echo $data->test;

Sending array to PHP using XMLHttpRequest (pure JS)

I'm attempting to send an array from JS to PHP using AJAX.
What seems to be happening is that the request is going through and is successful, but no data is received on the server (my test.php script needs the data from this array). Here is what I have so far...
Javascript
myButton.onclick = function() {
var xhr = new XMLHttpRequest();
xhr.open("POST", "test.php", true);
xhr.onreadystatechange = function () {
if (xhr.readyState==4 && xhr.status==200) {
console.log("Done. ", xhr.responseText);
}
}
//xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send('myArray='+JSON.stringify(myArray));
};
test.php
<?php
//$myArray = json_decode($_POST['myArray']); //Undefined index
print_r($_POST);
Note, myArray is not shown in the above code, but it is a valid array.
I've searched around SO (which led me to adding the 'setRequestHeader' in), as well as the wider internet. However, this has made no difference and I seem to be going round in circles. When I print $_POST, it's always an empty array.
I'm sure there's something I'm missing/misunderstanding.
Edit
As requested...
var myArray = ["John", "Jill", "James"];
I've also attempted this with an array of booleans, as well as an associative array/object.
Edit 2
As requested, adding screen shot from dev console...
you can use formData :
let data = new FormData();
let values = [1, 2, 3];
data.append('myArr', JSON.stringify(values));
// send data to server
and in php use json_decode :
$Values = json_decode($_POST['myArr']);
another way is to create HTML checkbox or select elements with javascript , assign values , serialize them and send them to back-end .

Accessing and decoding JSON sent from JavaScript to PHP

So I have a form, I took the contents of its inputs, threw them into an array, had it made into a JSON and then sent it to PHP so it can in turn decode and enter it into a database. I know it'd be easier to just use a <form method="POST" action="phpfile.php"> but I can't have this redirecting to another page, especially since my PHP is not embedded into HTML, instead it handles things offsite. Otherwise it'd be simpler to just use $_POST["name"] to get what I need. Nonetheless, this page in particular is supposed to create the user, receive a server response, that the user has been entered into the database and then is given an alert with a button to be redirected to the main page.
So anyway here are the relevant sections of this whole process.
JavaScript:
window.onload = function findSubmitButton() {
var button = document.querySelector(".send_info").addEventListener("click", serverInteraction);
}
function serverInteraction() {
var xmlhttp;
var inputArray;
var finalArray = [];
var JSONArray;
if (window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
throw new Error("Your browser is not compatible with XMLHTTP");
return false;
}
inputArray = document.querySelectorAll("input[type=text]");
for(var i = 0; i < inputArray.length; i++){
finalArray[i] = inputArray[i].value;
}
console.log(finalArray);
JSONArray = JSON.stringify({finalArray: finalArray});
console.log(JSONArray);
xmlhttp.open("POST","phpFiles/sendUserInfo.php", true);
xmlhttp.setRequestHeader("Content-type","application/json");
xmlhttp.send(JSONArray);
}
PHP:
<?php
$finalArray = json_decode($_POST['finalArray']);
var_dump($finalArray);
?>
That var_dump simply returns a null and using echo gives me nothing, except a warning that my array variable isn't initialized through XDebug. I'm not quite sure what I'm doing wrong here, I've been following this just like the tutorials tell you to do it, and isn't generating the array. I've also tried $_POST['JSONArray']without any luck in case that was how it was supposed to go. Also tried file_get_contents('php://input') which sends an empty string as well.
You can't get your data from $_POST if you put JSON in your post body.
see this question Receive JSON POST with PHP. php can't handle application/json properly.
For your var_dump is empty, try this
var_dump(file_get_contents('php://input'));
var_dump(json_decode(file_get_contents('php://input'), true));
you will see your data.
And if you send your data without change it to JSON, you will get wrong data.
eg: your finalArray is ['a','b','c'] and you send it directly.
var_dump(file_get_contents('php://input'));
you will see php got string a,b,c instead of ['a','b','c']
So if you want to use $_POST to receive data, you need to use application/x-www-form-urlencoded. you can use jquery to do it. see http://api.jquery.com/jquery.ajax/
$.ajax({
method: "POST",
url: "some.php",
data: { name: "John", location: "Boston" }
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
it will serialize your js object into x-www-form-urlencoded and php will handle it properly.
use chrome's dev tools, switch to network and see the request payload and response would be helpful for you.
You are bypassing $_POST by sending the the data as "Content-type","application/json" .
The data will instead be set in the body of request and can be retrieved using file_get_contents("php://input")
For further discussion see file_get_contents("php://input") or $HTTP_RAW_POST_DATA, which one is better to get the body of JSON request?
Generally there is no need to send your data as json to php

What is the correct way to send a JSON string between javascript and PHP?

I am trying to send a tiny bit of data from javascript using XMLHttpRequest and a Json string to a PHP script to process it and return some response in the form of a Json string again, but I've ran into tons of issues and different methods that just won't work together properly, here's what has worked so far:
Client
json_string = '{"foo":"1","bar":"2"}';
var r = new XMLHttpRequest();
r.open('post', 'script.php', true);
r.setRequestHeader('Content-type','application/json; charset=utf-8');
r.setRequestHeader('Content-length', json_string.length);
r.setRequestHeader('Connection', 'close');
r.onload = function () {
console.log(this.responseText);
};
r.send(json_string);
Server
$json = file_get_contents('php://input');
echo $json;
It can't get simpler than this, however I'm getting this warning:
[09-Jan-2015 15:50:03 America/Mexico_City] PHP Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0
[09-Jan-2015 15:50:03 America/Mexico_City] PHP Warning: Cannot modify header information - headers already sent in Unknown on line 0
And of course the response text looks like this:
Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0
Warning: Cannot modify header information - headers already sent in Unknown on line 0
{"foo":"1","bar":"2"}"
What am I doing wrong? Why does PHP complain about already sent headers?
I'm using PHP 5.6.
You need to edit your php.ini file and set always_populate_raw_post_data = -1.
Your code is working just fine. $json = file_get_contents('php://input'); is correct.
You are just getting a warning because your PHP was updated and you need to update the php.ini file for that new version.
More info here: https://www.bram.us/2014/10/26/php-5-6-automatically-populating-http_raw_post_data-is-deprecated-and-will-be-removed-in-a-future-version/
I looked at some of my old code that does do Ajax without Jquery. To send Json in a POST parameter is not that different from what you're doing already.
You really only need to change the headers you are setting, and give it a parameter name:
json_string = '{"foo":"1","bar":"2"}';
var r = new XMLHttpRequest();
r.open('post', 'script.php', true);
r.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
r.onload = function () {
console.log(this.responseText);
};
r.send('json='+encodeURIComponent(json_string));
And then, of course in PHP:
$_POST['json']
Edit: Added encodeURIComponent().

Variable target file with Ajax

I'd like to start by saying that I would rather any suggestions didn't include JQuery; I don't like how JQuery has become a defacto standard within JavaScript.
So here's my problem:
I'd like to pass a variable to a function that then uses that variable as the path to the file in a .open(). Here's my code so far:
Example of function being called:
ajaxPost('chatlog.txt',null);
The function being called:
function ajaxPost(targetPath,toSend){
var getMessage;
if (window.XMLHttpRequest){
getMessage=new XMLHttpRequest();
}
else{
getMessage=new ActiveXObject("Microsoft.XMLHTTP");
alert("Stop using Internet Explorer.");
}
getMessage.open("POST",targetPath,true);
getMessage.onreadystatechange=function(){
if (getMessage.readyState==4 && getMessage.status==200){
alert(getMessage.responseText);
}
};
getMessage.send(toSend);
}
This unfortunately doesn't work, for some kabuki reason.
I see some logical issue in your code:
the whole idea of using POST method is to send any kind of data to a specific backend and do server side stuff based on that data, but here you are using POST method to actually GET the 'chatlog.txt'. so you had to use GET method, to begin with.
BUT if you still insist on using POST instead of GET, you should know that you can use POST method instead of GET and it does the same, but you would face with some unforeseen problems.
YOUR ACTUAL PROBLEM:
I loaded your actual page and saw your problem, you have a error in your console:
Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
and as I said it means you have to change your method. I changed it like this:
function ajaxPost(targetPath,toSend){
var getMessage;
if (window.XMLHttpRequest){
getMessage=new XMLHttpRequest();
}
else{
getMessage=new ActiveXObject("Microsoft.XMLHTTP");
alert("Stop using Internet Explorer.");
}
getMessage.open("GET",targetPath,true);
getMessage.onreadystatechange=function(){
if (getMessage.readyState==4 && getMessage.status==200){
alert(getMessage.responseText);
}
};
getMessage.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
getMessage.send(toSend);
}
and it returned a data like this:
<b>Peck:</b> Hello World!<br/>#
<b>World:</b> Hello Peck!<br/>#
Add
getMessage.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
Before you send it. It tells the server how to process the POST stuff.
Using XMLHttpRequest is a very bad idea. If you are already using JQuery, try something like this:
$.post( "test.php", {name: "John", time: "2pm"}).done(function( data )
{
alert ("Succes! Data received: " + data);
});

Categories

Resources