javascript from ajax doesn't get proper execution - javascript

Using Ajax, I've created a sort of console that allows me to execute some PHP functions dynamically.
It looks like this
The problem is that after a bunch of commands, the console becomes hard to read. So I've created a javascript function, named "wipe();", which clears the <div> containing the console.
I tested this function with the developpers tools of chrome (the javascript console) and it works perfectly.
But when I try to call this function by making the PHP-AJAX return a "<script>wipe();</script>", it doesn't work. It does nothing.
I've read on the internet that all the "<script></script>" works independently from each other, but that you can call a <script>function</script> from another <script></script> block.
So why is it failing to do that ?
here is the php code :
echo '<script>wipe();</script>';
and here is the the first <script> block:
var xmlhttp = new XMLHttpRequest();
var span = document.getElementById("screen");
function send(data) {
window.setInterval(function() {
var elem = document.getElementById('screen');
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "./_rcons-transmetter.php?data="+data, true)
xmlhttp.onloadend = function() {
span.innerHTML = span.innerHTML+escapeHtml(data)+'<br>'+xmlhttp.responseText+'<br><br>';
}
xmlhttp.send();
}
function wipe(){
span.innerHTML = '';
}

To avoid security issues ( like a cross-site scripting attack) HTML5 specifies that a <script> tag inserted via innerHTML should not execute.
A way to execute the script is to evaluate the html using eval() . Be warned: using eval can be dangerous.
var xmlhttp = new XMLHttpRequest();
var span = document.getElementById("screen");
function send(data) {
window.setInterval(function() {
var elem = document.getElementById('screen');
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "./_rcons-transmetter.php?data=" + data, true)
xmlhttp.onloadend = function() {
span.innerHTML = span.innerHTML + escapeHtml(data) + '<br>' + xmlhttp.responseText + '<br><br>';
evalJSFromHtml(span.innerHTML);
}
xmlhttp.send();
}
function wipe() {
span.innerHTML = '';
}
function evalJSFromHtml(html) {
var newElement = document.createElement('div');
newElement.innerHTML = html;
var scripts = newElement.getElementsByTagName("script");
for (var i = 0; i < scripts.length; ++i) {
var script = scripts[i];
eval(script.innerHTML);
}
}
}

Call the 'wipe' function as a callback function directly from the 'send' function. Check status = 200 for a success response.
var xmlhttp = new XMLHttpRequest();
var span = document.getElementById("screen");
function send(data) {
window.setInterval(function() {
var elem = document.getElementById('screen');
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "./_rcons-transmetter.php?data="+data, true)
xmlhttp.onloadend = function() {
span.innerHTML = span.innerHTML+escapeHtml(data)+'<br>'+xmlhttp.responseText+'<br><br>';
}
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
wipe(); // 'Wipe' callback function
}
}
xmlhttp.send();
}
function wipe(){
span.innerHTML = '';
}

But when I try to call this function by making the PHP-AJAX return a "wipe();", it doesn't work. It does nothing.
try create script tag and add to document rather than change inner html.
var spaScript = document.getElementById("spaScript");
var wraper = document.createElement("div");
wraper.innerHTML = xmlhttp.responseText;
var script = document.createElement("script");
script.innerHTML = wraper.getElementsByTagName("script")[0].innerHTML;
spaScript.appendChild(script);

Test if wipe() is in the input and if it is trigger it instead of the ajax call
var xmlhttp = new XMLHttpRequest();
var span = document.getElementById("screen");
function send(data) {
if (data.indexOf('wipe()') == -1) {
window.setInterval(function() {
var elem = document.getElementById('screen');
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "./_rcons-transmetter.php?data=" + data, true)
xmlhttp.onloadend = function() {
span.innerHTML = span.innerHTML + escapeHtml(data) + '<br>' + xmlhttp.responseText + '<br><br>';
}
xmlhttp.send();
}
} else {
wipe();
};
}
function wipe() {
span.innerHTML = '';
}

inserting a script tag directly inside an element should not work (and by the way generating an error in the console).
Using the native eval() function on the response text without speciying the tag attribute should solve the problem.
on server side
echo 'wipe()';
on client side
eval(xmlhttp.responseText)

Related

Multiple files upload with ajax

I'm trying to make a script to upload multiple files using ajax, and print them on the screen with a loading circle display.
The script is working for one file, but I have a problem to make it works for multiple files. I guess it a "scope" problem. But my JS knowledge is not that good.
Also, I'm only using standard JS, no jQuery.
Here's the script :
var index_div = 0;
var dropper = document.querySelector('#upload');
dropper.addEventListener('dragover', function(e) {
e.preventDefault(); // Annule l'interdiction de "drop"
}, false);
dropper.addEventListener('dragenter', function() {
dropper.style.borderStyle = 'solid';
});
dropper.addEventListener('dragleave', function() {
dropper.style.borderStyle = 'dashed';
});
dropper.addEventListener('drop', function(e) {
e.preventDefault();
dropper.style.borderStyle = 'dashed';
var files = e.dataTransfer.files,
filesLen = files.length;
for (var i = 0 ; i < filesLen ; i++) {
var NomImage = files[i].name;
if(files[i] != '')
{
if(window.XMLHttpRequest)
{
xhr=new XMLHttpRequest();
}
    else if(window.ActiveXObject)
{
xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
var newDiv = document.createElement("div");
newDiv.setAttribute("class","image_div");
document.getElementById("upload").appendChild(newDiv);
document.getElementsByClassName("image_div")[index_div].innerHTML = '<img id="chargement" src="../includes/chargement.gif"/>';
    var form = new FormData();
    form.append('file', files[i]);
xhr.open('POST', "./traitement_upload.php", true);
xhr.onload = function (e) {
if(xhr.readyState==4 && xhr.status==200)
{
      document.getElementsByClassName("image_div")[index_div].innerHTML =
xhr.responseText;
index_div += 1;
    }
}
    xhr.send(form);
}
}
});
Sorry for the sloppy code. If I check the xhr readyState and status during the loop, the first(s) are 1 and 0, then the last one is good.
You can see I'm creating a new div for each uploaded file so I can print a thumbnail in it.
For what I understand, the code is processing while the ajax request is not done yet. The result is I only see the last file I submitted.
If I put a false to the async flag on xhr.open, it works but it doesn't show the loading gif of course.
Thank you for your help.
You should extract the code for AJAX functionality in a separate function - otherwise the closure for xhr.onload will use the current (at the time of calling) value of index_div - most probably the last one from the FOR cycle. Also, querySelector returns a collection - even if it finds just a single element, or even if it finds nothing. Also, you should use both event.dataTransfer and event.target in order to handle both drag/drop and normal clicking.
var dropper = document.getElementById('upload');
dropper.addEventListener('dragover', function(e)
{
e.preventDefault();
dropper.style.background = '#eee';
}, false);
dropper.addEventListener('dragenter', function()
{
e.preventDefault();
dropper.style.background = '#eee';
}, false);
dropper.addEventListener('dragleave', function()
{
e.preventDefault();
dropper.style.background = '#fff';
}, false);
dropper.addEventListener('drop', uploadFile, false);
document.getElementById('file_upload').addEventListener('change', uploadFile, false);
function uploadFile(e)
{
e.preventDefault();
dropper.style.background = '#fff';
dropper.style.borderStyle = 'dashed';
var files = (e.dataTransfer || e.target).files,
filesLen = files.length;
for (var i = 0 ; i < filesLen ; i++)
{
if(files[i] != '')
{
var newDiv = document.createElement("div");
newDiv.setAttribute("class","image_div");
newDiv.innerHTML = '<img id="chargement" src="../includes/chargement.gif"/>';
document.getElementById("upload").appendChild(newDiv);
doAJAX(newDiv,files[i]);
}
}
}
function doAJAX(div,file)
{
var form = new FormData();
form.append('file', file);
if(window.XMLHttpRequest)
{
xhr=new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open('POST', "./traitement_upload.php", true);
xhr.onload = function (e)
{
if(xhr.readyState==4 && xhr.status==200)
{
div.innerHTML = xhr.responseText;
}
}
xhr.send(form);
}

update function on ajaxObject

When a button is clicked on the webpage a table of data is displayed. I want to scrape that data but I can't find where it comes from in the website source code.
This is the tag for the button:
<button type="submit" onclick="divChangeStateOn('load-raw-0062294377Amazon.com'); getRaw('0062294377', 'Amazon.com', 'lr-0062294377Amazon.com',this);"style="margin-bottom: 4px; width: 120px; text-align: left;" name="load-raw"><img src='images/workstation.png'/> raw data</button>
I believe that the getRaw function is where the data comes from (I'm not positive about this) so I looked at the javascript code for the getRaw function
function getRaw(asin, store, res, caller)
{ document.getElementById(res).innerHTML = '<p align="center" valign="top"><img align="center" src="phpmy_loading.gif"></p>';
var poststr = "raw=" + encodeURI(asin) +
"&site=" + encodeURI(store);
var updateResults = new ajaxObject(res, 'extra.php', caller);
updateResults.update(poststr);
}
I have been having a hard time finding any documentation about ajaxObject and can't find any information about the update function. What is ajaxObject.update doing and is it possible for me to access the data that appears when the button is clicked?
function divChangeStateOn(divID)
{ var divElem = document.getElementById(divID);
divElem.style.display = 'block';
}
EDIT: The link to the source code view-source:http://www.ranktracer.com/account_workstation.php it might be password protected but I was just using the demo version
EDIT 2:
I am basically trying to write a script that replicates the Ajax http request. This where I am at, it doesn't work and I am especially concerned about where data = uri
x = time.time()
print x
timestamp = datetime.fromtimestamp(x/1000.0)
print timestamp
uri = "raw=0062294377&site=Amazon.com&timestamp="+str(timestamp);
url = "lr-0062294377Amazon.com"
length = str(len(uri))
headers = {'X-Requested-With': 'XMLHttpRequest',
"Content-type": "application/x-www-form-urlencoded",
"Content-length": length,
"Connection" : "close"}
s = Session()
r = s.post(url= url, data= uri, headers= headers)
The entire code for ajaxObject is present in the link you provided. Please let us know what help you are expecting here?
function ajaxObject(layer, url, caller) {
if (caller) {
disableButton(caller, 'disable');
}
var that = this;
var updating = false;
this.callback = function() {}
var LayerID = document.getElementById(layer);
this.update = function(passData) {
if (updating == true) {
return false;
}
updating = true;
var AJAX = null;
if (window.XMLHttpRequest) {
AJAX = new XMLHttpRequest();
} else {
AJAX = new ActiveXObject("Microsoft.XMLHTTP");
}
if (AJAX == null) {
alert("Your browser doesn't support AJAX.");
return false
} else {
AJAX.onreadystatechange = function() {
if (AJAX.readyState == 4 || AJAX.readyState == "complete") {
if (caller) {
disableButton(caller, 'enable');
}
LayerID.innerHTML = AJAX.responseText;
delete AJAX;
updating = false;
that.callback();
}
}
var timestamp = new Date();
var uri = passData + '&timestamp=' + (timestamp * 1);
AJAX.open("POST", url, true);
AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
AJAX.setRequestHeader("Content-length", uri.length);
AJAX.setRequestHeader("Connection", "close");
AJAX.send(uri);
return true;
}
}
}

Calling data from JSON file using AJAX

I am trying to load some data from my JSON file using AJAX. The file is called external-file.json. Here is the code, it includes other parts that haven't got to do with the data loading.The part I'm not sure of begins in the getViaAjax funtion. I can't seem to find my error.
function flip(){
if(vlib_front.style.transform){
el.children[1].style.transform = "";
el.children[0].style.transform = "";
} else {
el.children[1].style.transform = "perspective(600px) rotateY(-180deg)";
el.children[0].style.transform = "perspective(600px) rotateY(0deg)";
}
}
var vlib_front = document.getElementById('front');
var el = document.getElementById('flip3D');
el.addEventListener('click', flip);
var word = null; var explanation = null;
var i=0;
function updateDiv(id, content) {
document.getElementById(id).innerHTML = content;
document.getElementById(id).innerHTML = content;
}
updateDiv('the-h',word[i]);
updateDiv('the-p',explanation[i])
function counter (index, step){
if (word[index+step] !== undefined) {
index+=step;
i=index;
updateDiv('the-h',word[index]);
updateDiv('the-p',explanation[index]);
}
}
var decos = document.getElementById('deco');
decos.addEventListener('click', function() {
counter(i,-1);
}, false);
var incos = document.getElementById('inco');
incos.addEventListener('click', function() {
counter(i,+1);
}, false);
function getViaAjax("external-file.json", callback) { // url being the url to external File holding the json
var r = new XMLHttpRequest();
r.open("GET", "external-file.json", true);
r.onload = function() {
if(this.status < 400 && this.status > 199) {
if(typeof callback === "function")
callback(JSON.parse(this.response));
} else {
console.log("err");// server reached but gave shitty status code}
};
}
r.onerror = function(err) {console.log("error Ajax.get "+url);console.log(err);}
r.send();
}
function yourLoadingFunction(jsonData) {
word = jsonData.words;
explanation = jsonData.explanation;
updateDiv('the-h',word[i]);
updateDiv('the-p',explanation[i])
// then call whatever it is to trigger the update within the page
}
getViaAjax("external-file.json", yourLoadingFunction)
As #light said, this:
function getViaAjax("external-file.json", callback) { // url being the url to external File holding the json
var r = new XMLHttpRequest();
r.open("GET", "external-file.json", true);
Should be:
function getViaAjax(url, callback) { // url being the url to external File holding the json
var r = new XMLHttpRequest();
r.open("GET", url, true);
I built up a quick sample that I can share that might help you isolate your issue. Stand this up in a local http-server of your choice and you should see JSON.parse(xhr.response) return a javascript array containing two objects.
There are two files
data.json
index.html
data.json
[{
"id":1,
"value":"foo"
},
{
"id":2,
"value":"bar"
}]
index.html
<html>
<head>
</head>
<body onload="so.getJsonStuffs()">
<h1>so.json-with-ajax</h1>
<script type="application/javascript">
var so = (function(){
function loadData(data){
var list = document.createElement("ul");
list.id = "data-list";
data.forEach(function(element){
var item = document.createElement("li");
var content = document.createTextNode(JSON.stringify(element));
item.appendChild(content);
list.appendChild(item);
});
document.body.appendChild(list);
}
var load = function()
{
console.log("Initializing xhr");
var xhr = new XMLHttpRequest();
xhr.onload = function(e){
console.log("response has returned");
if(xhr.status > 200
&& xhr.status < 400) {
var payload = JSON.parse(xhr.response);
console.log(payload);
loadData(payload);
}
}
var uri = "data.json";
console.log("opening resource request");
xhr.open("GET", uri, true);
xhr.send();
}
return {
getJsonStuffs : load
}
})();
</script>
</body>
</html>
Running will log two Javascript objects to the Dev Tools console as well as add a ul to the DOM containing a list item for every object inside the data.json array

Javascript interfering with each other

As I know very little about Javascript and Jquery I am hoping to be able to get an answer here.
Here is the code in my <head></head> of my document.
<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/functions.js" type="text/javascript"></script>
<script type="text/javascript" src="js/jscolor/jscolor.js"></script>
<script type="text/javascript">
var current_shouts = 0;
function $(eleid) {
return document.getElementById(eleid);
}
function urlencode(u) {
u = u.toString();
var matches = u.match(/[\x90-\xFF]/g);
if (matches) {
for (var mid = 0; mid < matches.length; mid++) {
var char_code = matches[mid].charCodeAt(0);
u = u.replace(matches[mid], '%u00' + (char_code & 0xFF).toString(16).toUpperCase());
}
}
return escape(u).replace(/\+/g, "%2B");
}
function shouts() {
clearTimeout(getshout);
var xmlHttp = (window.XMLHttpRequest) ? new XMLHttpRequest : new ActiveXObject("Microsoft.XMLHTTP");
xmlHttp.open("GET", "../shoutbox/shouts.php?i=" + Math.random());
xmlHttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (parseInt(this.responseText) > current_shouts) {
getshouts();
current_shouts = parseInt(this.responseText);
}
getshout = setTimeout("shouts()", 1000);
}
}
xmlHttp.send(null);
}
function getshouts() {
var xmlHttp = (window.XMLHttpRequest) ? new XMLHttpRequest : new ActiveXObject("Microsoft.XMLHTTP");
xmlHttp.open("GET", "../shoutbox/getshouts.php?i=" + Math.random());
xmlHttp.onreadystatechange = function() {
if (this.readyState == 4) $("shoutbox").innerHTML = this.responseText;
$("shoutbox").scrollTop = $("shoutbox").scrollHeight;
}
xmlHttp.send(null);
}
function push_shout() {
shout();
return false;
}
function shout() {
var xmlHttp = (window.XMLHttpRequest) ? new XMLHttpRequest : new ActiveXObject("Microsoft.XMLHTTP");
xmlHttp.open("POST", "../shoutbox/shout.php");
var data = "user=" + urlencode($("user").value) + "&" + "shout=" + urlencode($("shout").value);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", data.length);
xmlHttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (!this.responseText) $("shout").value = "";
else {
$("console").innerHTML = this.responseText;
setTimeout("$('console').innerHTML = ''", 5000);
}
getshouts();
}
}
xmlHttp.send(data);
return true;
}
var getshout = setTimeout("shouts()", 1000);
</script>
It seems when I put the typed code above everything, it does not work, but the others do, if the code sits as it is shown above it works, but the scripts above it do not work anymore.
I have tried $.noConflict(); but it seems it did nothing, so I am not sure what I am to do here.
Any suggestions?
try something like:
$j = jQuery.noConflict();
then you can use $j to refer to the jQuery object whenever you need to.
I had a problem with jQuery plugins clashing somehow.
I loaded both into the head of the html document, between consecutive separated script tag zones. Then I used:
window.onload = function() {function01(); function02();};
to load each function in an orderly fashion and separately.
It worked for me this time.

Ajax Call Only Works the First Time

My JavaScript/ajax code works the first time, but not there after. The GetAttribute element is null when the function is called again. I have try using createElement and AppendChild, but it does the same thing. If I didn't need the getAttribute it would work fine, but I cannot get the function to work with the getAttribute method. Any help would be appreciated.
function ajaxFunction(Picked) {
var getdate = new Date();
if(xmlhttp) {
var Pic1 = document.getElementById("Pic1").getAttribute("name");
var Pic2 = document.getElementById("Pic2").getAttribute("name");
if (Picked === Pic1 ){
var Chosen = Pic1;
var NotChosen = Pic2;
}
else {
var Chosen = Pic2;
var NotChosen = Pic1;
}
xmlhttp.open("POST","choice.php",true);
xmlhttp.onreadystatechange = handleServerResponse;
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send("Chosen=" + Chosen + "&NotChosen=" + NotChosen );
}
}
function handleServerResponse() {
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
var response = xmlhttp.responseText;
response = response.split("|");
document.getElementById('Pic1').innerHTML = response[0];//New Pic
document.getElementById('Pic2').innerHTML = response[1];
}
else {
alert("Error. Please try again");
}
}
}
Change your if to
if (Picked === Pic1)
By writing if (Picked = Pic1 ), you're assigning Picked to Pic1.

Categories