Website working, but not on iphone. XMLHttpRequest() error - javascript

I have created this website
http://www.tylertracy.com/testing/Xml/App%20veiwer%205-28.php
It works fine on most browsers and on iPhone simulators, but it doesn't work on a real iPhone. I have narrowed it down to the XMLHttpRequest(). It seems that when I am getting the xml, I can not read the children of [object Element] it returns undefined. This is very baffling i do not understand.
Here is my code for getting the XML
function convertXml (path) {
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest(); // code for IE7+, Firefox, Chrome, Opera, Safari
}else{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); // code for IE6, IE5
}
xmlhttp.open("GET",path,false);
xmlhttp.send();
xml=xmlhttp.responseXML.getElementsByTagName("app");
var foo = [];
for (var i = 0; i <= xml.length-1; i++) {
foo[i] = {};
for (var j = 0; j <=xml[i].children.length-1; j++) { // get all children of the app and make it a part in the object
foo[i][xml[i].children[j].tagName] = xml[i].children[j].innerHTML.trim();//super complicated
}
}
return foo;
}
After much experimenting i have discovered that on iPhone the request returns a [object Document] while the computer returns a [object XMLDocument]. I don't know what this means, but i feel like it is where my problem is coming from. is there a way of maybe converting between these?
I have since then updated the code to jQuery seeing if the issue still persists, which it does.
Here is the new jQuery
function getXML (path) {
//gets text version of the xml doc
var response = $.ajax({ type: "GET",
url: "testingXml.xml",
async: false,
}).responseText;
//converts text into xmlDoc
parser=new DOMParser();
xmlDoc=parser.parseFromString(response,"text/xml");
return xmlDoc;
}
function xmlToObject (x) {
var xml = x.getElementsByTagName("app"); //get all the xml from the root
var foo = [];
for (var i = 0; i <= xml.length-1; i++) {
foo[i] = {}; // make the object
for (var j = 0; j <=xml[i].children.length-1; j++) { //get all of the children of the main tag
foo[i][xml[i].children[j].tagName] = xml[i].children[j].innerHTML.trim(); //super complicated
}
}
return foo;
}
Then to get the array, you would write this code xmlToObject(getXML("testingXml.xml"))
The issue is still happening, on computer it is fine, but on iPhone (Google, Safari, Firefox, Oprah) It seems that the xml just isn't displaying.

I'm getting
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/
in the Google Chrome console when opening your page. This could be why it won't load on iOS: instead of just logging a warning, Apple decided to ignore such requests on mobile devices to prevent the browser from freezing.
Try with
xmlhttp.open("GET",path,true);
and a xhr.onload handler as described in MDN's "Synchronous and asynchronous requests".

Related

What is different about xmlhttprequest in Firefox

My code works in Chrome and Safari, but it hangs in FF.
I removed the parts of the code that aren't necessary.
I used console commands to show how far the first loop gets, and it will do the second log fine right before the xhr open and send commands.
If the open/send commands are present the loop only happens once, if I remove the open/send commands the loop completes successfully.
Currently using FF 62nightly, but this issue has plagued me since Quantum has come out and I'm now trying to figure out why it doesn't work right.
for (i = 0; i < length; i++) {
(function(i) {
// new XMLHttpRequest
xhr[i] = new XMLHttpRequest();
// gets machine url from href tag
url = rows[i].getElementsByTagName("td")[0].getElementsByTagName('a')[0].getAttribute('href');
// Insert the desired values at the end of each row;
// will try to make this customizable later as well
insertVNC[i] = rows[i].insertCell(-1);
insertSerial[i] = rows[i].insertCell(-1);
insertVersion[i] = rows[i].insertCell(-1);
insertFreeDiskSpace[i] = rows[i].insertCell(-1);
// the fun part: this function takes each url, loads it in the background,
// retrieves the values needed, and then discards the page once the function is complete;
// In theory you could add whatever you want without taking significantly longer
// as long as it's on this page
console.log(i);
xhr[i].onreadystatechange = function() {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
}
};
//"Get" the "Url"... true means asyncrhonous
console.log(url);
xhr[i].open("GET", url, true);
xhr[i].send(null);
})(i); //end for loop
}
I cannot tell you why it gives issues in Firefox. I would not trust sending off arbitrarily many requests from any browser
I would personally try this instead since it will not fire off the next one until one is finished
const urls = [...document.querySelectorAll("tr>td:nth-child(0) a")].map(x => x.href);
let cnt=0;
function getUrl() {
console.log(urls[cnt]);
xhr[i].open("GET", urls[cnt], true);
xhr[i].send(null);
}
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
if (cnt>urls.length) getUrl();
cnt++;
}
}
getUrl();

jQuery xmlParse not working in IE

I am building a photo slider in JavaScript and jQuery. It works perfectly in chrome, but not in IE6 where I know most of my clients would view it.
I have this function:
function getFacebookPhotos(photoCount, pageId) {
var picsUrl = "http://api.facebook.com/method/fql.query?query=SELECT%20src_big,%20src_big_height,%20src_big_width%20FROM%20photo%20WHERE%20pid%20IN%20(SELECT%20pid%20FROM%20photo_tag%20WHERE%20subject='243117879034102')%20OR%20pid%20IN%20(SELECT%20pid%20FROM%20photo%20WHERE%20aid%20IN%20(SELECT%20aid%20FROM%20album%20WHERE%20owner='" + pageId + "'%20AND%20type!='profile'))";
var responseText = $.ajax({
url: picsUrl,
async: false,
dataType: "xml",
success: function(text) {
responseText = text;
}
}).responseText;
var xmlDoc = $.parseXML(responseText);
var $xml = $(xmlDoc);
var $photos = $xml.find("photo");
var resultantPhotos = [];
for (var i = 0; i < photoCount; i++)
{
var $element = $($photos[i]);
var $src_big = $element.find("src_big");
var $text = $src_big.text();
resultantPhotos.push($text);
}
return resultantPhotos;
}
It fetches the XML response from a facebook query, parses it, and returns an array of photo urls from a facebook page. In Chrome, this works, but in Internet Explorer 6, the returned photo array is null. In both browsers the code executes without error.
I was using this JavaScript to parse the XML:
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
else {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open("GET", picsUrl, false); // Throws permission error in IE
xmlHttp.send(null);
var photos;
if (window.DOMParser)
{
var parser = new DOMParser();
xml = parser.parseFromString(responseText, "text/xml");
}
else // Internet Explorer
{
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(responseText);
}
photos = xml.getElementsByTagName("photo");
But that gave me errors in IE while still working in Chrome so I switched to jQuery.
Do you know what's wrong with it?
This may or may not be accurate, but I think the solution is to not use javascript at all, but to use PHP instead.
My errors were caused by javascript's lack of permission to access remote files. When I tried retrieving the XML output first with this PHP code:
<?php file_put_contents("query.xml", file_get_contents($facebookPicsUrl)); ?>
My javascript code
xml.open("GET","query.xml",false);
worked perfectly, but it made me realize that I should be using PHP, not only because downloading an xml file to my server is clunky, but because PHP can do everything that my JS is doing with simplexml_load_file. Everywhere I went looking for "how to get IE to open remote XML," they flat out say "you can't." Regardless of whether or not it's possible, it will be much easier to do this in PHP.

XML to JSON works in firefox but produces TypeError in chrome

Im porting a browser extension from FF to chrome. I have this XMLHttpRequest, which works fine:
var xhrdata = new XMLHttpRequest(),
xhrdata.onreadystatechange = function () {
if (xhrdata.readyState === 4) {
if (xhrdata.status === 200) {
getJXONTree(xhrdata.responseXML);
}
}
};
xhrdata.open("GET", "mydomain.com/my.xml", true);
xhrdata.responseType = "document";
xhrdata.send();
This send the .responseXML over to this function (shortened)
function getJXONTree(oXMLParent) {
var vResult = true, nLength = 0, sCollectedTxt = '';
if (oXMLParent.hasAttributes()) {
vResult = {};
[...]
This works absolutely fine in firefox, but in chrome, polling the exact same XML with the exact same code, I get this error:
TypeError: Object #<Document> has no method 'hasAttributes'
What am I missing here?
Firefox is more lenient when it comes to this, but it has to be:
xhr.responseXML.documentElement
since documents dont have any attributes. thanks #robW

Ajax script fails in IE8

The following script executes and works fine in Safari, Chrome and Firefox - but not in IE8. Unfortunately IE8 is one of my targeted browsers so this is a bit of a problem. Since I don't have a lot of experience with Ajax I'm not really sure where to begin looking either.
I've noted that IE reports an error on line 15 (marked with **) which doesn't really make sense as the if-else should stop it from even looking at that line.
function getNames(str) {
var xmlhttp;
// Clear previous queries
if(str.length == 0){
document.getElementById("txtHint").innerHTML = "";
return;
// Due to the high number of possible hits we'll demand 3 chars
// before we start querying.
}else if(str.length < 3){
return ;
}
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.status == 200 && xmlhttp.readyState == 4){
// String from get_names.php is comma separated
var arr = xmlhttp.responseText.split(",");
// The UL list we want our names in
var ul = document.getElementById("names");
// Clear the list for each key in
if(ul.hasChildNodes()){
while(ul.childNodes.length >= 1){
ul.removeChild(ul.firstChild);
}
}
// Step trough the String in Array form
for(var i = 0; i < arr.length; i++){
// :# means that we've reached the end of applicable names.
if (arr[i] != ":#") {
var li = document.createElement("li");
li.innerHTML = newListItem = arr[i];
// Inserts the current name into the list.
ul.insertBefore(li, ul.getElementsByTagName("li")[0]);
}
}
}
}
xmlhttp.open("GET", "./ext/get_names.php?q=" + str, true);
xmlhttp.send();
}
You should first check the readyState and then check the status. This is a common error that is reported but ignored in most browsers. I'm not sure that this is the solution to your problem, but since you haven't provided the error message, it's hard to help you further.
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// Code ...
}
As far as I know the 'window.XMLHttpRequest'-check should be ok.
You could try taking a look at this answer. In that case, the problem was that native xmlhttprequest was disabled in the browser settings.

The entity name must immediately follow the '&' (...)

Seems like a common error, but none of the solutions I've found searching have proved successfull (replacing & with & is one). I have a simple Javascript (AJAX) that includes a couple of double if statements. The script works fine in both Chrome and Firefox, but not in IE9 which reports an error on the same line as Netbeans (the entity name must immediately follow the '&' (...)).
Hoping that someone here can spot the error or provide clues to where I shoud look.
function getNames(str) {
var xmlhttp;
if (str.length == 0) {
document.getElementById("txtHint").innerHTML = "";
return;
}
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 () {
// The line below is what produces the error.
if (xmlhttp.status == 200 && xmlhttp.readyState == 4) {
var arr = xmlhttp.responseText.split(",");
var ul = document.getElementById("names");
var li = document.createElement("li");
if (ul.hasChildNodes()) {
while (ul.childNodes.length >= 1) {
ul.removeChild(ul.firstChild);
}
}
for (var i = 0; i < arr.length; i++) {
if (arr[i] != ":#") {
var li = document.createElement("li");
li.innerHTML = newListItem = arr[i];
ul.insertBefore(li, ul.getElementsByTagName("li")[0]);
}
}
}
}
xmlhttp.open("GET", "./ext/get_names.php?q=" + str, true);
xmlhttp.send();
}
You can enclose the script within a CDATA section:
<script type="text/javascript">
//<![CDATA[
document.write("&&");
//]]>
</script>
Unless you have a particular reason, the cleanest solution is usually moving your javascript code to an external file.
Besides avoiding most odd problems with browsers interpreting included javascript differently, it also makes things more cacheable.
Jukka K. Korpela explained an IE9 quirks mode behavior in a comment to this answer
This is bug in IE 9 (in Quirks Mode), since by the spefications, &#x2022 is valid here. But it has always been good and recommended practice to end all entity references (like ) and character references (like é) with a semicolon, partly because omitting it has triggered various browser bugs.
I disagree on what the specification says, but IE9 quirks mode may be the culprit.

Categories

Resources