[SOLVED]
I have a terrible headache, because I am new to JS and AJAX/JSON and cannot seem to figure out why this is happening. I am getting a JSON formatted response that looks like this when output on my client web page:
[{"ticket_id":"2","ticket_name":"super_rugby_18_Aug_2017","ticket_desc":"Brumbies vs Sharks, 14:30","ticket_price":"420.00"}]
The problem is, that I cannot parse the responseText with JSON. But whenever I hardcode the parsed string to be [{"ticket_id":"2","ticket_name":"super_rugby_18_Aug_2017","ticket_desc":"Brumbies vs Sharks, 14:30","ticket_price":"420.00"}], the problem goes away.
But of course, I need the database request to be parsed and not the hardcoded string. Please help. Here is my code that is not working:
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var input = String(this.responseText);
var jsonObj = JSON.parse(input);
document.getElementById("history").innerHTML = jsonObj[0].ticket_id;
}
}
Hardcoded 'string' variable that can be parsed:
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var string = '[{"ticket_id":"2","ticket_name":"super_rugby_18_Aug_2017","ticket_desc":"Brumbies vs Sharks, 14:30","ticket_price":"420.00"}]';
var jsonObj = JSON.parse(string);
document.getElementById("history").innerHTML = jsonObj[0].ticket_id;
}
}
Here is the output of stringify:
"\r\n\r\n\r\n\r\n\r\n\r\n\r\n[{\"ticket_id\":\"1\",\"ticket_name\":\"IIC_match3\",\"ticket_desc\":\"\",\"ticket_price\":\"589.99\"},{\"ticket_id\":\"2\",\"ticket_name\":\"super_rugby_18_Aug_2017\",\"ticket_desc\":\"Brumbies vs Sharks, 14:30\",\"ticket_price\":\"420.00\"}]\r\n\r\n" The array is filled in this php loop:
php loop I use to send the JSON array
$rows = array();
while ($r = mysqli_fetch_assoc($result)){
$rows[] = $r;
}
$json = json_encode($rows);
echo $json;
SOLUTION:
Guess what the problem was? My web service is running in a Linux VM environment, and my calling web client was too. Now when I tried doing the httprequest from a WINDOWS machine to the VM, the JSON.parse works! What could be wrong with my Linux configuration?
Related
I want to send data with the POST method to a php server, then retrieve data from the server, using GET method this time (I assume).
Here's the JS :
function send()
function send(leURL, laValeur) {
try {
return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open('POST', leURL);
req.setRequestHeader("Content-Type", "application/json");
req.onreadystatechange = function() {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
document.getElementById("result").innerHTML = "Ok!";
}
};
jmail = JSON.stringify(laValeur);
req.send(jmail);
resolve("true");
});
}
catch (err) {
window.alert("erreur 2");
}
}
function recieve()
function recieve(laURL) {
try {
var reqt = new XMLHttpRequest();
reqt.open('GET', laURL);
reqt.onreadystatechange = function(e) {
if (this.readyState == XMLHttpRequest.DONE && this.status = 200) {
var rep = JSON.parse(this.responseText);
try {
window.alert(rep);
}
catch (e) {
window.alert("erreur 4");
}
}
}
reqt.send();
//return rep;
}
catch (e) {
window.alert("erreur 3");
}
}
function calls :
//there's a form in the HTML (id="form")
document.getElementById("form").addEventListener('submit', function(evt) {
evt.preventDefault();
send(url, mail)
.then(recieve(url));
});
Old recieve() function (for testing purposes) :
function recieve(laURL) {
window.alert(laURL);
}
So, as long as I was using old recieve() function, I had send() print "Ok!" and recieve() creating an alert, which makes me think it worked fine. But now that I use the new recieve() function, the page just reloads. (No catch block is even displayed !)
Here's the PHP :
<?php
if (!empty($_POST)) {
$var = //do something with the data, involving $_POST
echo $var;
}
else {
echo "Hello, there !";
}
?>
Since $var was generated out of the first HTTP request (POST), how do I retrieve it in javascript ?
I suspect the error is caused either by the php or because of using two XMLHttpRequests (still I don't know how I should do this using only one HTTP request)
Your PHP stores the data in a variable, echos it out, then exits.
At this point, the PHP program has finished, the memory gets cleaned up, and the variable no longer exists.
If you want the data to be available to another request, then you have to store it somewhere persistent such as a session or a database.
If you want to use a single request, then read this.responseText in the readyStateChange handler.
The POST request already returns the value (using echo). All you need to so is show it using your JavaScript.
e.g. in the POST request:
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
document.getElementById("result").innerHTML = this.responseText;
}
I don't see any need for the GET request, unless you intend to use this at a later time in your process, expecting that the data may have changed on the server. But for that to make any sense, you have to have stored the data somewhere on the server, and also send in the request some identifier telling the server which piece of data to retrieve.
What do you do with your data ?
How do you store them ?
How do you retreive them on the server to sending them after to the client if needed ?
You should store the $var somewhere, generally we use session $_SESSION for that. All depends of what you want finally.
Documentation for PHP session : https://www.php.net/manual/fr/reserved.variables.session.php
Once you have start the session,
I think you want to do something like that:
<?php
if ($_SESSION['var']) {
echo "already done";
...
} else {
if(!empty($_POST)) {
$_SESSION['var'] = //do something with the data, involving $_POST
echo $_SESSION['var'];
} else {
echo "var = not done, post = empty";
}
}
?>
I'm trying to handle a simple XML file with JS (server-side). So far, with every solution I've tried out, the value shows as "undefined".
I've tried a couple of different approaches, yet I still cannot get past loading the XML file itself and successfully displaying it.
When I've tried to parse it with a DOMParser, the node value is "undefined" (see the present code please).
Another approach I've taken before is to treat it as an XML file without changing it to string beforehand - then I get the '.getElementsByTagName('node')[0]; is not a function' error.
function loadXML(postID){
var xmlhttp = new XMLHttpRequest();
var file = 'logs/queue'+postID+'.xml';
xmlhttp.onreadystatechange = function() {
console.log('[DEBUG]Readystate: '+this.readyState+', status: '+this.status);
if (this.readyState == 4 && this.status ==200) {
myFunction(this);
};
function myFunction(xmlfile) {
var xmlDoc=null;
var data = "";
var parser = new DOMParser();
var user;
xmlDoc = parser.parseFromString(String(xmlfile), "text/xml");
var nodes = xmlDoc.getElementsByTagName("node");
for(i=0; i< nodes.length; i++){
tipper = nodes[i].getAttribute("id");
}
console.log(user)
}
};
xmlhttp.open("GET", file, true);
xmlhttp.send();
}
My only expectation is to obtain the node attribute value of the "node" element.
Instead, I keep getting the "undefined" value as a result.
After two days of struggling with this matter, I finally came up with a working solution.
Therefore, in case somebody was having a problem similar to mine, here goes:
First, I've npm-installed libxmljs. From this point, after quickly checking its wiki page, things went almost silky smooth. The modified code can be analyzed below:
function loadXML(postID){
var xmlhttp = new XMLHttpRequest();
var file = 'file.xml';
xmlhttp.onreadystatechange = function() {
console.log('[DEBUG]Readystate: '+this.readyState+', status: '+this.status);
if (this.readyState == 4 && this.status ==200) {
myFunction(this);
};
}
function myFunction(xmlfile) {
var xmlDoc = libxmljs.parseXml(xmlfile.responseText);
var nodes = xmlDoc.root().childNodes();
var node = nodes[0];
var node_id = xmlDoc.get('//user').attr('id').value();
var uname = xmlDoc.get('//name');
var uamount = xmlDoc.get('//u_amount');
var umessage = xmlDoc.get('//u_message');
console.log('[DEBUG] [id=%s] User: %s. Amount: %s. Message: %s.', node_id, uname.text(), uamount.text(), umessage.text() );
}
xmlhttp.open("GET", file, true);
xmlhttp.send();
};
The background is, frontend passed an id back to backend and backend uses the id to extract information from database. The extracted data need further processing at backend and then gets sent back to frontend.
Here is the front end code:
html:
<!DOCTYPE html>
<html>
<head>
<title>Test!</title>
<meta charset="utf-8">
<script src="loadPage.js">
</script>
</head>
<body onload = "loadPage()">
<div id="stack"><p>test part</p>
</div>
</body>
</html>
js:
function __getParameters() {
var parm = {};
var url = window.location.href;
var pairs = url.slice(url.indexOf('?') + 1).split('&');
for (var i = 0; i < pairs.length; i++) {
pair = pairs[i].split('=');
parm[pair[0]] = pair[1];
}
return parm;
}
function __loadData(star) {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// var data = JSON.parse(xmlhttp.responseText);
console.log(xmlhttp.responseText);
if (xmlhttp.responseText == "") {
document.getElementById("stack").innerHTML = "f*ck";
} else {
document.getElementById("stack").innerHTML = xmlhttp.responseText;
}
}
}
var url = "getXML.pl";
url = url + "?STAR=" + star;
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function loadPage() {
var parm = __getParameters();
// document.getElementById("stack").innerHTML = parm["STAR"];
if (parm == undefined) {
// wrong url error page
} else if (parm['STAR'] == undefined) {
// missing star error page
} else if (parm['user' == undefined]) {
// missing user id error page
} else {
var star = parm["STAR"];
var user = parm["user"];
__loadData(star);
}
}
The backend uses perl to extract data from database, and it will print the output to stdout. The output is a XML in string form. Then I must use an existed python script to process the extracted data.
However, the server seems not support python (But the server can run python if I directly run python scripts on it. The reason for my statement is that I wrote a python cgi and I got a 500 error, while the perl cgi is ok. I'm sure the python script is correct since it can run directly on the server. I have no access to error log and I cannot modify the config file of the server).
So I piped the output of the perl script to python, and run it using 'system()'. The python script will output a processed string to stdout.
Here is the backend scripts:
perl script:
#!/depot/perl-5.14.2/bin/perl
# extract posted data
local ($buffer, #pairs, $pair, $name, $value, %FORM);
$ENV{"REQUEST__METHOD"} =~ tr/a-z/A-Z/;
if ($ENV{"REQUEST_METHOD"} eq "POST") {
read(STDIN, $buffer, $ENV{"CONTENT_LENGTH"});
} else {
$buffer = $ENV{"QUERY_STRING"};
}
#pairs = split(/&/, $buffer);
foreach $pair (#pairs) {
($name, $value) = split(/=/, $buffer);
$value =~ tr/+/ /;
$value =~ s/%(..)/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
$star = $FORM{STAR};
print "Content-type:text/html\n\n";
my $cmd = "***/sq_star.pl --xml --star_id " . $star;
$cmd = $cmd . " | ***/python parseXML.py";
system($cmd);
the sq_star.pl (I just remove the path here and replace it with ***) near the end of perl script is just an existed script that will extract data from database. And parseXML.py is an existed script which does a lot to the input string.
The strange thing is, the responseText is always an empty string. I tried to run the perl script directly on the server, it can print expected results. And if I remove $cmd = $cmd . " | ***/python parseXML.py";, the responseText will be the data extracted from the database.
What I have tried for now:
1. I wrote a simple test python with just one line of print. Still empty response
2. I tried to store the output as $output =`$cmd`; and print $output; in the perl script, still empty.
3. I tried to store the original data in a txt and let the python read from the txt. Still empty
It seems that that data processed by python just cannot be sent back .....
-------------------update----------------
It seems to be the problem of the server. I guess the server is not set to support python so if I directly send requests to a python script on backend, there will be 500 error. But somehow my way, i.e., calling python in perl, gets around the error, but still the python just doesn't work... Just my guess
I found the problem. It is because the interpreter I specified cannot be found by the server. system(...) line actually doesn't run at all. The reason that I didn' t see any error is because system() hides the error for me. Actually the return value of system() is -1, which means something wrong. I should have checked the return value
I have a problem that I unable to save data that are parsed from Javascript into PHP. The problem came when I implement WordPress. On single index.html it is working and data able to store in the database.
On Javascript file : (send data)
var dbParam = JSON.stringify(data);
console.log(dbParam);
var obj, dbParam, xxmlhttp;
xxmlhttp = new XMLHttpRequest();
xxmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
// document.getElementById("demo").innerHTML = this.responseText;
}
};
xxmlhttp.open("GET", "http://localhost/trackpage/dummy-data/saveDB.php?x=" + dbParam, true);
xxmlhttp.send();
console.log("send");
On PHP file: (get data)
header("Content-Type: application/json; charset=UTF-8");
$obj = json_decode($_GET["x"], false);
$conn = new mysqli ("localhost", "root", "", "laravelcrudwebapp");
$stmt = $conn->prepare("INSERT INTO tracks (data1,data2) VALUES (?, ?, )");
$stmt->bind_param("ss",$obj->data1,$obj->data2);
$stmt->execute();
$stmt->close();
$conn->close();
If you're going to send your data as a GET parameter, you have to URL-encode it first:
var dbParam = encodeURIComponent(JSON.stringify(data));
However, I will point out that it is extremely bad practice to perform write operations via GET requests. You're leaving yourself wide open for all sorts of abuse and cross-side scripting attacks. For starters, you can read this post, as well as do some research on Google:
https://softwareengineering.stackexchange.com/questions/188860/why-shouldnt-a-get-request-change-data-on-the-server
//Sent an ajax http post request to a php file on the server, the post //request is a simple object.
var xhr = new XMLHttpRequest();
var person = {
"firstName" : "Adebowale",
"lastName" : "Johnson",
"ago" : 43
}
xhr.open("POST","phfile.php",true);
xhr.setRequestHeader("Content-type","application/x-www-form- urlencoded");
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
var status = xhr.status;
if((status >= 200) && (status < 300) || (status === 304)) {
alert(xhr.responseText);
}
}
};
xhr.send(JSON.stringify(person));
//if I do alert(xhr.responseText);
//I get object{} from the browser.
//On the server, using php, how do I access the object, if I do echo or //print_r, I get the empty object --- object{} with none of the properties.
//As you can tell from the tone of my question, am still very new to all //these, am just trying to learn please.
//on my phfile.php, I set up the following php code...
<?php
print_r
//How do I access the object I sent to this file please
?>
I dont see the need for JSON.stringify(person) in your AJAX request, since all the keys of the Object are already in strings.
Since you are using POST method, you can directly access the object like
print_r ($_POST['person']);
You can read raw POST data using STDIN:
$post_data = fopen("php://input", "r");
$json = fgets($post_data);
$object = json_decode($json);
$firstName = $object->firstName;
$lastName = $object->lastName;
$age = $object->age;
You could simplify all of this by just passing the data as URL-encoded form fields:
xhr.send('firstName=' + encodeURIComponent(person.firstName) + '&lastName=' + encodeURIComponent(person.lastName) + '&ago=' + encodeURIComponent(person.ago);
Then you can just access them as $_POST['firstName'], etc. in PHP.