Im trying to send a string to a php server, but for some reason, Im not able to read the string on the server... I tried many ways to type it well but it seems like I never got the correct syntax. Anyone have clues?
var command="";
if(document.getElementById("Text_1").value != "" && document.getElementById("Text_2").value != "")
{
command += " " + document.getElementById("Text_1").value + " " + document.getElementById("Text_2").value;
}
alert(command);
xmlhttp.open("POST", "server.php", false);
xmlhttp.setRequestHeader('info', command)
//TRIED xmlhttp.setRequestHeader("info, command")
//TRIED xmlhttp.setRequestHeader('info', 'command')
//TRIED many others sketchy things...
xmlhttp.send();
//TRIED xmlhttp.send(command);
var output = xmlhttp.responseText;
On php server :
<?php
$parameter = $_POST['command'];
$output = exec("someexecutable.exe $parameter");
echo json_encode($parameter);
?>
For them wondering, if I hardcode $parameter with a right string, it works, so the executable isn't the problem. The server just cant get the value of the string in $_POST.
setRequestHeader is used to set headers on the request. Things like Content-type and Content-length.
You need to pass the data to send(). For $_POST to work, they need to be in key=val&vey2=val2 format. Actually, in newer browsers, you can use FormData.
xmlhttp.open("POST", "server.php", false);
// To emulate a `<form>` POST
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// To get the response, you need to set a callback
xmlhttp.onreadystatechange = function(){
// readyState 4 = complete
// status = 200 OK
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var output = xmlhttp.responseText;
}
};
// Create the Form Data
var params = new FormData;
params.append('command', command);
xmlhttp.send(params);
P.S. You should run escapeshellarg() before running your command. This could be worse than just SQL injection if people can run arbitrary commands on your server.
<?php
$parameter = escapeshellarg($_POST['command']);
$output = exec("someexecutable.exe $parameter");
?>
P.P.S. escapeshellarg() will make your command treat the entire $_POST['command'] string as one parameter. If you don't want that, then you'll need to POST an array from your JavaScript.
// Create the Form Data
var params = new FormData;
params.append('command[]', document.getElementById("Text_1").value);
params.append('command[]', document.getElementById("Text_2").value);
xmlhttp.send(params);
Now $_POST['command'] will be an array, so you'll have to run the command like so:
<?php
$parameters = array_map('escapeshellarg', $_POST['command']);
$output = exec("someexecutable.exe ".implode(' ', $parameters));
?>
Related
I want to build a simple program using XMLHttpRequest to calculate the area of the triangle. I used this code for client-side;
<body>
<form>
<label for="txtLength">Length</label>
<input type="text" id="txtLength" name="txtLength"><br><br>
<label for="txtWidth">Width</label>
<input type="text" id="txtWidth" name="txtWidth"><br><br>
<input type="hidden" name="submitted" value="1">
<input type="button" name="Calculate" value="Calculate" onclick="calArea();">
</form><br><br>
<div id="showArea">Enter Values and click Calculate.</div>
<script type="text/javascript">
function calArea() {
var len = document.getElementById("txtLength").value;
var wid = document.getElementById("txtWidth").value;
var sub = 1;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.readyState == 200) {
document.getElementById("showArea").innerHTML = xhttp.responseText;
}
};
xhttp.open("POST", "calculate_area.php", true);
xhttp.send(len&wid&sub);
}
</script>
</body>
This code is for the server side.
<?php
print_r($_POST);
if (isset($_POST['sub'])) {
$len = $_POST['len'];
$wid = $_POST['wid'];
$area = (($len*$wid)/2);
echo $area;
}
else{
echo "Not input detected.";
}
?>
Even tried so many codes, It doesn't send the data to server side.
I found the mistake. I was sending the parameters as part of the URL, but need to send them as part of the request body.
Client-side code;
function calArea() {
var len = document.getElementById("txtLength").value;
var wid = document.getElementById("txtWidth").value;
var sub = 1;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("showArea").innerHTML = xhttp.responseText;
}
};
xhttp.open("POST", "calculate_area.php", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.send(JSON.stringify({len: len, wid: wid, sub: sub}));
}
Server-side code;
if (isset($_POST['sub'])) {
$len = $_POST['len'];
$wid = $_POST['wid'];
$area = (($len*$wid)/2);
echo $area;
}
else{
echo "Not input detected.";
}
len&wid&sub
Taking some variables and putting the Bitwise & between them is not going to give you a useful value to submit to the server.
You need to encode the data in a format that you can transmit over HTTP and which your server-side code can read.
PHP supports URL Encoded and Multipart Form Encoded data natively so pick one of those.
The URLSearchParams API will generate URL Encoded data for you.
e.g.
xhttp.send(new URLSearchParams({ len, wid, sub }));
Passing a URLSearchParams object will also let XHR automatically set the correct Content-Type request header so PHP will know what it needs to do to decode the data and populate $_POST with it.
You need to put all the parameters into a string of the form name=value with each one separated by &. And the values should be encoded in case they contain special characters.
You also need to set the content type so this data will be parsed correctly.
So change
xhttp.send(len&wid&sub);
should be:
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send(`len=${encodeURIComponent(len)}&wid=${encodeURIComponent(wid)}&sub=${encodeURIComponent(sub)}`);
I am a beginner and I am trying to echo arrays and append them into a html division i created. The AJAX call I made was successful but the response was not appearing inside the division i assigned it to. Upon further inspection, I found out that the response I have received has an array length over 600 ( I am expecting 10 records). So there must be something wrong with my echo PHP file or the receiving end of the HTML file but just cannot figure out what that is.
Here are my codes:
listdiscount.php
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
$conn = new mysqli("localhost", "root", "root", "bencoolen");
$userid = $_GET['userid'];
$result = $conn->query("select userid, codename from discountcode where userid ='" . $userid . "' ");
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
printf("Userid: %s '' Codename: %s", $row["userid"], $row["codename"]);
}
$conn->close();
?>
index.html ( with js codes )
<html>
<script>
function mydiscount(){
var userid = "jimmy";
var xmlhttp = new XMLHttpRequest();
var url = serverURL() + "/listdiscount.php";
url += "?userid=" + userid;
alert(url);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert("readystate=4 and status =200");
mydiscountresult(xmlhttp.responseText);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function mydiscountresult(response) {
var arr = response;
alert(arr); //alerted
alert(arr.length); //alerted 600+ arrays
alert("mydiscountresult working"); //alerted
var i;
$("#discountcontent").empty();
for(i = 0; i < arr.length; i++) {
$("#discountcontent").append("<b>" + arr[i].userid + "</b>"+ arr[i].codename + "<hr>");
}
}
mydiscount();
</script>
<div data-role="content" class="ui-content" id="discount">
LIST OF DISCOUNT CODE:<br>
<div id="discountcontent" class="ui-grid-solo">
</div>
</div>
</html>
Here is what my response look like when alerted:
addition note: my php files are in different folder so serverurl() is declared and used here.
the get request returns a json array so you need to convet it in to normal array using json parse. you may please change the line of code as
mydiscountresult(JSON.parse(xmlhttp.responseText));
It will work fine.
The Function xmlhttp.responseText retun a String, right?
You gave this string into function mydiscountresult and copy it into variable var. It is still a string, isn't it?
So the alerts work fine and do there jobs on the string (length 600 and so on)
Then you walk over this string letter by letter (this is what your for-loop is doing). On every letter var[i] you try to read a property userid. I think no normal letter (calld char) hav a property called userid. So this result in an empty string.
I think you would like to get the array from the string xmlhttp.responseText. To do so you just let JSON parse this string and it gave you an Object.
JSON.parse(xmlhttp.responseText)
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
I have created an YouTube search engine that sends video id, title etc. using session. I have created buttons with unique ids for each of them, onclicking which a page is called via ajax and the session is generated using the unique id for that button.
The javascript code is like follows:
<script type="text/javascript">
function loadXMLSession(videoid, videotitle) {
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "GenerateDownloadSession.php?videoid=" + videoid + "&videotitle=" + videotitle, true);
xmlhttp.send();
//strip off spaces and embed dashes - clean urls
var downloadtitle = videotitle;
downloadtitle = downloadtitle.toLowerCase();
downloadtitle = downloadtitle.replace("-"," ");//strip off dashes with spaces
downloadtitle = downloadtitle.replace(/ +(?= )/g,'');//replace multiple spaces with one space
downloadtitle = downloadtitle.replace(/[`~!##$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '');//strip off all special characters from video title
downloadtitle = downloadtitle.replace(/ /g,"-");//replace spaces with dashes
downloadtitle = downloadtitle.replace(/-+$|(-)+/g, '$1');//replace multiple dashes with single dash
var url = window.location.hostname;
url = "/development"//only for development phase
url = url+"/download/"+downloadtitle+".html";
window.location=url;
}
</script>
The download buttons are coded as follows:
echo "<button id=\"downloadbtn\" class=\"btn\" value = \"" . $YouTubeVideoID . "\" onclick=\"loadXMLSession(this.value,'" . $VideoContent['6'] . "')\"><img src=\"" . $HostURLRedirect . "/img/Arrow-Down-icon.png\" alt=\"download\" /> Download</button> ";
The php page called by ajax has simple session creation:
session_start();
$videoid = $_GET['videoid'];
$videotitle = $_GET['videotitle'];
$_SESSION['DownloadID'] = $videoid;
$_SESSION['DownloadTitle'] = $videotitle;
$_SESSION['DownloadType'] = "Download";
The problem that I am having is, when I click on any of the download button for the first time after opening the browser, it is working well. But when I search again, it is returning the previous session values. I am calling the session function through ajax and passing values to it. And, it should overwrite the session values. But in this case, it is not overwriting the values. How can I overcome this issue? Any suggestions?
At
xmlhttp.open("GET", "GenerateDownloadSession.php?videoid=" + videoid + "&videotitle=" + videotitle, true);
xmlhttp.send();
you are doing an asynchronous Request, which means, that the javascript continues after sending the request, not waiting for it to complete. Most likely it will hit your redirect of your current page to the download before the call could change the Session data.
Solution 1.) Make the script synchronous by setting the last parameter to false.
Solution 2.) Move your forward logic into the onreadystatechange callback function.
on a side node: why using ajax for this? you could simple pass the parameters appended to the url when forwarding...?
Do you have the GET-Values set when requesting your Script?
Use your Firebug to check what is answered by the PHP-Script. (Network -> you will see the requested file being loaded when your Ajax Request is being started).
you should change the location of you page once you get the ajax response:
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
var downloadtitle = videotitle;
downloadtitle = downloadtitle.toLowerCase();
downloadtitle = downloadtitle.replace("-"," ");//strip off dashes with spaces
downloadtitle = downloadtitle.replace(/ +(?= )/g,'');//replace multiple spaces with one space
downloadtitle = downloadtitle.replace(/[`~!##$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '');//strip off all special characters from video title
downloadtitle = downloadtitle.replace(/ /g,"-");//replace spaces with dashes
downloadtitle = downloadtitle.replace(/-+$|(-)+/g, '$1');//replace multiple dashes with single dash
var url = window.location.hostname;
url = "/development"//only for development phase
url = url+"/download/"+downloadtitle+".html";
window.location=url;
}
}
But I most be honest, I dont see the point of using ajax and then changing the location of the actual page.
Maybe you should start the download in another window?
I'm playing around a little with Ajax and i'm using the following code.
var r = new XMLHttpRequest();
r.open("POST", "pythonTesting.php", true);
r.onreadystatechange = function () {
if (r.readyState === 4 && r.status === 200) {
alert("Success: " + r.responseText);
}
};
r.send("text=yellow");
It is successful but the alert isn't showing the actual responseText.
pythonTesting.php (not to be confused by the name) is just:
<?php
echo $_POST['text'];
?>
I'm expecting the responseText to be yellow because that's how I sent it but its not. I'm not really seeing what the problem is though. It must be one of those easy to fix mistakes.
from http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp:
xmlhttp.open("POST","ajax_test.asp",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Henry&lname=Ford");
Since this is a post I believe you will need to set the length:
r.setRequestHeader("Content-length", "text=yellow".length);
send the variables through the address:
r.open("POST", "pythonTesting.php?text=yellow", true);
then retrieve the variable in php by
$text = $_REQUEST['text'];
So I must be missing something. I can retrieve the zpid and the zestimate no problem doing the following:
$zdata->response->zpid; //zpid
$zdata->response->zestimate->amount; //zestimate
But then when I try what appears to be the obvious equivalent to retrieve a part of the address:
$zdata->response->address->street;
$zdata->response->address->city;
None of it works! Why?? Clearly I must be missing something here. Below is my entire code
<?php
$zillow_id = '1234';
$search = $_POST['address'];
$citystate = $_POST['csz'];
$address = urlencode($search);
$citystatezip = urlencode($citystate);
$url = "http://www.zillow.com/webservice/GetSearchResults.htm?zws-id=".$zillow_id."&address=".$address."&citystatezip=".$citystatezip;
$result = file_get_contents($url);
$data = simplexml_load_string($result);
$zpidNum = $data->response->results->result[0]->zpid;
$zurl = "http://www.zillow.com/webservice/GetZestimate.htm?zws-id=".$zillow_id."&zpid=".$zpidNum;
$zresult = file_get_contents($zurl);
$zdata = simplexml_load_string($zresult);
//echo $zdata->response->zestimate->amount;
//$zestimate=$zdata->response->zestimate->amount;
$zstreet=$zdata->response->address->street;
echo $street;
?>
Looking at the XML output as seen on Zillow's own documentation, I am following the same pattern to try to get the street as to get the zestimate. I am not very familiar with working with XML so it is very possible I am missing something.
So I am getting an error in my console that shows the following:
Uncaught SyntaxError: Unexpected token T
The 'T' seems to be the first letter of the street that is entered, as it changes accordingly. Perhaps this could shine some light on the issue?
I'll post my AJAX too but I don't know why there would be something wrong with it. As stated above, I am able to display the ZPID and Zestimate just fine, only the address isn't working.
AJAX/JS:
function validateAddress(){
var address = document.getElementById('address').value;
var csz = document.getElementById('city_state_zip').value;
if (address == null || address == "" || csz == null || csz == "") {
return false;
}
else{
getZestimate(address,csz);
}
}
function getZestimate(address,csz){
var xmlhttp = new XMLHttpRequest();
var userdata = "address="+address+"&csz="+csz;
xmlhttp.open("POST","../wp-content/themes/realhomes/submit_address.php",true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
//retrieve = JSON.parse(xmlhttp.responseText);
retrieve = xmlhttp.responseText;
document.getElementById("zestimateArea").innerHTML = '<div id="zillowWrap"><img src="http://www.zillow.com/widgets/GetVersionedResource.htm?path=/static/logos/Zillowlogo_150x40.gif" width="150" height="40" alt="Zillow Real Estate Search" id="ZillowLogo" /><span id="zestimateTag">Zestimate®</span></div><span id="zestimatePrice">'+retrieve+'</span><div id="zillowDisclaimer"><span>© Zillow, Inc., 2006-2014. Use is subject to Terms of Use</span><span>What’s a Zestimate?';
}
else{
document.getElementById("zestimateArea").innerHTML = "Error!"
}
}
xmlhttp.send(userdata);
document.getElementById("zestimateArea").innerHTML = "Generating...";
return false;
}
So when I went to post my AJAX as a last ditch effort for help I had seen I still had this line of code:
retrieve = JSON.parse(xmlhttp.responseText);
As Daedalus helpfully explained, this wasn't an issue when I was retrieving integers but posed a problem when I was retrieving text. I had originally put that line of code in when I was trying to retrieve both the Zestimate and the address together in an array encoded with JSON. When it was unsuccessful I took a step back to see if I could retrieve the address individually with no success. I never thought twice about that line of code since the AJAX still seemed to work fine.
Hence the perplexing outcome.
Changing that line back to:
retrieve = xmlhttp.responseText;
Allowed me to retrieve the address with success.
Don't you had simple mistakes that cause huge problems? Back to figuring out why the JSON encode and parsing wasn't working, but that's a question for a different post.