Data not being sent via XMLHttpRequest - javascript

I have a weird issue with a script I am using to send some info to my PHP. I say weird because this code is a direct copy of some already working code on the same application, with new variable names. I need to upload a small amount of data to my server, and while the value is there and the code runs all the way through, the POST data is not being sent or something. I have checked, and it says it has been submitted to my PHP with the value but nothing happens. I am using Vue.js if there are questions about some of my formatting
I have tried looking at other examples online, but my thing is that this was a block of code that copied from a working part of my application. It works until the data transfer from JS -- PHP
JS
editDisplayName: function() {
var self = this;
var newName = prompt("10 Characters Max, 3 Min", "Enter Display Name");
if(newName.length <= 10 && newName.length >= 3 ) {
var sendData = new XMLHttpRequest();
sendData.open("POST", "primary.php", true);
sendData.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
sendData.send(newName);
self.username = window.localStorage.getItem('username');
window.localStorage.clear();
}
}
PHP
function changeUsername() {
// Connect to Server
$link = // Commented Out For Security;
if (mysqli_connect_error()) {
die ("DB Connection Error");
}
$newName = $_POST['newName'];
$newName = mysqli_real_escape_string($link, $newName);
$token = $_COOKIE['validToken'];
$token = mysqli_real_escape_string($link, $token);
$query = "UPDATE userData SET username = '$newName' WHERE token = '$token' LIMIT 1";
mysqli_query($link, $query);
mysqli_close($link);
echo("
<script>
var username = $newName;
window.localStorage.setItem('username', username);
</script>
");
}
if(isset($_POST['newName'])) {
changeUsername();
}
I'm expecting on my DOM that I would have the new username set, instead it is blank. The spot where stuff stops working is somewhere with the POST data being sent, since my PHP isn't picking anything up, but I can't figure out what is wrong.

Instead of just sending the value, you should send the parameter name as well.
So, instead of using sendData.send(newName);, try using:
sendData.send("newName=" + newName);
(as your Content-type is application/x-www-form-urlencoded)
Or if you want to use JSON:
Change your Content-type to application/json, then send the data as a JSON string, like so:
sendData.send(JSON.stringify({'newName': newName}));

Related

Can't send data from JavaScript to PHP [duplicate]

This question already has answers here:
Receive JSON POST with PHP
(12 answers)
Closed 1 year ago.
I am trying to make a simple JavaScript game, and as a user, I will get a score.
I want to send this score to a PHP server, but in my case, I can't get this data in the PHP file.
Here my JavaScript code:
var obj = {
"note": 0,
};
obj.note = score;
console.log(obj.note)
var data, xml, txt = "", mydata;
data = JSON.stringify(obj.note);
xml = new XMLHttpRequest();
xml.onreadystatechange = function() {
if (this.readystate == 4 && this.status == 200) {
mydata = JSON.parse(this.responseText);
for (x in mydata) {
txt += mydata[x];
}
// document.getElementsByClassName("pEl").innerHTML = txt;
}
};
xml.open("POST", "getnote.php", true);
console.log("true");
xml.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xml.send("x=" + data);
Here my PHP code:
<?php
// Takes raw data from the request
$json = file_get_contents('application/x-www-form-urlencoded');
// Converts it into a PHP object
$data = json_decode($json);
echo $data
?>
Many people tried to help you, you used a valid sample which you linked, anyway still using the wrong code, which you modified with no reason and all you had to do was to follow suggestions from GeeksForGeeks page you linked.
Short
You can not use anything you want when you trying to access php://input stream (you used application/x-www-form-urlencoded, which is wrong, and I have no even idea why?)
Working, minified sample
test.html
<script>
let obj = {
"note": 123,
"foo": "bar"
};
let data, xml;
data = JSON.stringify(obj);
xml = new XMLHttpRequest();
xml.open("POST", "getnote.php", true);
xml.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xml.send(data);
</script>
getnote.php
<?php
// Takes raw data from the request
$json = file_get_contents('php://input');
// Converts it into a PHP object
$data = json_decode($json, true);
// print whole array decoded from JSON object
print_r($data);
// print single node of the array
echo "The sent note is: {$data['note']}";
echo "The sent foo is: {$data['foo']}";
// etc.
Please, read once again the article you linked, also read carefully the question linked by El Vanja to recognize what mistake you did.
Note: that should be just a comment, and probably will be flagged to delete, anyway I have no idea what else we can do if you don't want to read the simple comments that solve your problem and give you a detailed description.

JavaScript problem with fetching data from PHP

I'm new to PHP, and i'm trying to fetch data from PHP to JavaScript. When i do that, JavaScript always giving me the same error "Unexpected token < in JSON at position 0". I don't have any idea what to do. I'm stuck...Help Help ! x)
There is the code
JavaScript
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myObj.name;
}
};
xmlhttp.open("GET", "data.php", true);
xmlhttp.send();
PHP
<?php
$myObj->name = "John";
$myObj->age = 30;
$myObj->city = "New York";
$myJSON = json_encode($myObj);
echo $myJSON;
?>
I think you are getting an issue of object
Object $myObj need to be initialized before using it
I have updated the code (Initialized the object) please use the below code on php page to resolve the issue
<?PHP
$myObj = new StdClass();
$myObj->name = "John";
$myObj->age = 30;
$myObj->city = "New York";
$myJSON = json_encode($myObj);
echo $myJSON;
Obviously, the response returned for your XMLHttpRequest is not a valid JSON. Provided that your PHP codesample is complete, PHP will most likely(*) echo an E_WARNING error before outputting the JSON string, although your code will work. Related question and solution here. Easiest way to check is to view the raw response in your browser's dev tools (supported by all major browsers). If the response contains anything except the JSON string, JSON.parse() will throw an error.
(*)This depends on your error reporting settings

Randomly occuring Unexpected end of JSON on GET request

I'm developing a simple web project where one of the features (Related to the error) will display a quote, credit and source. This feature works as intended using setInterval every 12seconds to call a function which will make a connection to my XAMPP hosted MYSQL server and return a random row as a JSON object which I can use to display on the page. below is the Quote retrieval script and PHP:
quotes.js
(function() {
ajax = new XMLHttpRequest();
var method = "GET";
var url = "data.php";
var asynchronous = true; // revise asynchronous
var quoteContainer = document.getElementById("quote");
var authorContainer = document.getElementById("author");
function getQuote() {
ajax.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200) {
var data = JSON.parse(this.responseText);
console.log(data)
quoteContainer.innerHTML = "\"" + data.Quote + "\""
authorContainer.innerHTML = data.Author + " - " + "<a href='"+ data.Source +"' target='_blank'>source</a>";
}
}
ajax.open(method,url,asynchronous);
ajax.send();
}
getQuote();
setInterval(getQuote,12000); //set to 100 for testing
}());
Data.php
<?php
// write secondry query for seasonal messages
$conn = mysqli_connect("localhost","root","","quotes_db");
$sql = "SELECT * FROM quote_table ORDER BY RAND() LIMIT 1;";
$result = mysqli_query($conn,$sql);
$data= mysqli_fetch_assoc($result);
echo json_encode($data);
?>
The issue is that on random occasions while this is running the server returns a 'null' packet (with the titled error) I have checked the network data using Chromes developer console and the effected packets are empty and take slightly longer to return. I have checked my database table for special characters and it all seems normal. due to the packet returning null the page is left empty
How can I stop this error appearing, so that I can get a continuous stream of random rows from my table?
If the answer is not an obvious one what bug-testing steps should I take to find a fix?
If more information is needed I can update this post.
Error log
This usually happens when the data returned is undefined or is not in a valid format. That is when JSON.parse() would fail. You can consider putting try-catch block.
try {
var data = JSON.parse(this.responseText);
} catch(e) {
console.log('Unable to parse the string.')
}
Also, consider wrapping the JSON.parse() statement in an if condition, if server sends an empty response.
You can do some kind of error handling to achieve your goal.
ajax.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200) {
try
{
var data = JSON.parse(this.responseText);
}
catch (error)
{
if (error instanceof SyntaxError)
{
// unable to parse the result to json
// maybe retry?
// do some kind of errer handling
}
}
}
Using the try-catch statement you simply catch the error instead of stopping the script from executing so you are able to handle errors yourself.
Best regards.
EDIT:
setInterval(function ()
{
var found = false;
var attemptCount = 0;
var allowedAttempts = 10; // your exit condition, so you wont get stuck in an infinite loop if the server is broken or something
while (!found && attemptCount < allowedAttempts)
{
try
{
getQuote();
}
catch (error)
{
if (error instanceof SyntaxError)
{
attemptCount++;
continue;
}
}
found = true;
}
}, 12e3);
EDIT No.2: (based on your comment on another answer)
If you want to do some server-side validation, you have to modify the PHP-Code:
$data = []; // set a default return value
$result = mysqli_query($conn,$sql);
if (mysqli_num_rows($result) === 1) // we found a result
{
$data= mysqli_fetch_assoc($result);
}
echo json_encode($data);
So, if you combine both, the client- and server-side validation you should be fine for sure:
What did we do?
we implemented a server side validation, so the result that is returned to the client should never throw an error when going through JSON.parse(). To make this work you have to implement a client-side validation on the result of JSON.parse() to make sure that you got a valid result (because it could be an empty array).
if any errors occur on the server (for whatever reason) and the returned result cannot be parsed, we simply retry the entire process for n times.
Best regards.
The issue is caused by your encoding: Jean de La Bruyère is transmitted as Jean de La Bruy�re by MySQL.
PHP json_encode() is not able to deal with the encoding of the French character as shown in this print_r() output of the mysqli_fetch_assoc() result:
Array
(
[QuoteID] => 6
[Quote] => Those who make the worst use of their time are the first to complain of its brevity.
[Author] => Jean de La Bruy�re
[Source] => https://www.goodreads.com/author/show/778012.Jean_de_La_Bruy_re
)
As json_encode() is only accepting UTF-8 encoded strings ("All string data must be UTF-8 encoded.", cf. PHP Documentation), you can tell MySQL to return every result in UTF-8 encoding by simply executing the following query once after opening the connection:
mysqli_query($conn, "SET NAMES 'utf8'");

How to post JSON or form data with vanilla JavaScript AJAX

I hate using libraries unless I absolutely need them. I prefer working with vanilla JavaScript as I think it will do what I want and I will know better what I'm doing. So, there is a simple add-record operation I want to do via AJAX:
function addToBlacklist() {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'api.php?action=addToBlackList');
var jsonObj;
xhr.onreadystatechange = function () {
try {
jsonObj = JSON.parse(xhr.responseText);
} catch (e) {
alert(e.toString());
}
if (jsonObj.status_code === 200) {
alert('Added');
//Add the new word to the end of the list in the grid view
} else {
alert('Add failed');
}
}
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('blackword=' + encodeURIComponent(document.getElementById('blackword')));
}
On server side, I process the request this way (Already set header at the top of the page with header('Content-Type: application/json') :
if(isset($_GET['action'])){
$action = filter_input(INPUT_GET, 'action', FILTER_SANITIZE_URL);
switch('action'){
case 'addToBlacklist':
error_log('Action: ' . 'addToBlackList');
$blackword = filter_input(INPUT_POST, 'blackword', FILTER_SANITIZE_URL);
if(file_put_contents(BLACKLIST_FILE, $blackword . PHP_EOL, FILE_APPEND)){
echo json_encode(['status_code'=>200, 'description'=>Translate::get('Adding to blacklist successful')]);
}
else {
echo json_encode(['status_code'=>500, 'description'=> Translate::get('Adding to blacklist failed')]);
}
break;
}
}
The problem is I always get this error in my browser:
SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
Make sure you always send valid JSON string from the server. On the client side, check, whether the response status is valid (HTTP status code 200) and only then proceed to parse the XHR response.
The value, you get from server is empty, that is the problem.
At first, JSON.parse() expects JSON string as a parameter, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse.
Second, the switch statement in your php code is incorrect for multiple reasons:
It uses hardcoded string 'action' as parameter - I suppose there should be $action var as param
It is missing a defalut clause - this results in returning nothing, which can not be parsed as JSON by javascript - I suggest you to use some fallback JSON string to make sure, that there is always a JSON-type string response from the server in case of successful response. (Should switch statements always contain a default clause?)

$_GET variable not showing up in string and boolean operations

I have a javascript file that uses POST to send some data to a PHP file, as such:
var additional = "Feb2015";
xmlhttp.open("POST", "database_comm_general.php?query=" + additional, true);
In the PHP file, I use $_GET to get that 'additional' variable:
$query = $_GET['query'];
Now, if I want to use it to get some data from MySql, I use this for my query, but when I echo it, it just shows empty quotation marks, where 'Feb2015' should be:
$sql_query = "SELECT * FROM '" . $query . "'";
Output: "SELECT * FROM ''"
Even more odd, if I use json_encode and print it on the javascript side, it shows up just fine.
Similarly, if I see if the variable equals 'Feb2015', with json_encode it will return true, but on the page it will output false at the same time.
Any ideas?
Edit:
This is my javascript code:
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var content = JSON.parse(this.responseText);
window.alert(content);}}
xmlhttp.open("POST", "database_comm_general.php?query=" + additional, true);
xmlhttp.send();
Alright, I haven't been able to fix this exact issue, but I got my code working through other means:
First, I use jquery instead of javascript for communicating with PHP:
text = "Feb2015";
$.ajax(
{ url : "database_comm_general.php?" + text, success: function(data){
var return_data = JSON.parse(data);
populateTableList(return_data);
}});
Second, in the PHP file, I don't use $_GET, I get the data from the link address:
$link = $_SERVER[REQUEST_URI];
$index = strpos($link, "?");
$sub_string = substr($link, $index+1, 7);
$sub_string = $sub_string;
Third, I added a single line of code in the MySQL code that resolved the issues with some of the arrays which couldn't be encoded:
mysqli_set_charset($conn, 'utf8');
All in all, I feel I've been to hell and back, but I hope this helps someone in the future.

Categories

Resources