Written on 2 September 2005
Currently I'm working on debugging a very complicated script that's supposed to xmlhttprequest a few pages to be shown in a "Dashboard". I already wrote about another aspect of the project in my previous entry, but now that I'm concentrating on the XMLHTTP aspects of this project I found out a few very interesting things about
responseXML, as well as a complicated Explorer bug.
This entry treats these two points, since they should be documented.
Once an xmlhttprequest has come back from the server it's time to read out the server's reply and do something with it. There are two ways of reading out the reply:
responseXML. Not surprisingly, the first gives the reply as plain text, while the second offers an XML document.
responseXML is only available if the server sends back an XML document with MIME type
text/xml, and not if it sends back, for instance, an HTML document.
This is quite annoying, because it invalidates a xmlhttp/accessibility approach I've been considering for some time now.
Exception: Opera allows you to read out the
responseXML of an HTML document.
Ideally, I'd like to be able to do the following:
<a>tags that point to an HTML document, and set some advanced event handlers on them.
The simplest way of getting this to work is using HTML pages for both situations. In order to work properly without xmlhttprequest, the HTML page should be complete, ie. it should contain
<body> tags. We should strip all these tags away, though, if the HTML page arrives by xmlhttprequest.
Unfortunately, as we just saw, HTML pages are not available as
responseXML, but only as
responseText, since HTML pages do not have MIME type
text/xml. Therefore their document tree is inaccessible, and we can't change their structure.
A partial solution is given by the
overrideMimeType() method of xmlhttp. It basically says that the returned document should be treated as having the given MIME type, no matter what the server says. Use:
var xmlhttp = [initialize new XMLHTTP request]; xmlhttp.open('page.html', etc.) xmlhttp.overrideMimeType('text/xml'); xmlhttp.send(null);
Now the returned document is considered to be XML, and
overrideMimeType() method doesn't work in Explorer Windows. It doesn't work in Opera, either, but there
responseXML is always available anyway, so we don't need this method.
So far so bad. I believe that the original creator of the script I'm working on found out that
responseXML didn't work on HTML pages in Explorer, and that he opted for another solution, one that at first sight seems quite useful, but that unfortunately triggers a bug.
The Dashboard should not show the complete HTML page, including style sheets,
<body> tags and such. Instead, it should only show the
<div id="content"> in the page. In itself this is an excellent idea. Extract this div, move its children to the Dashboard, and the site uses an xmlhttp script while retaining accessibility.
However, in order to use the W3C DOM to extract the correct div, we need an XML document, and as we saw before
responseXML doesn't work for HTML pages, least of all in Explorer Windows. Only
responseText is available.
We could write an entire XML parser to parse
responseText, but that's rather a lot of work. What the creator of the script did instead, is loading the
responseText into an intermediate element, a created
<div> that's not part of the document but floats around in the hyperspace of the browser object model. Simplified code:
// page has been loaded by now var container = document.createElement('div'); container.innerHTML = xmlhttp.responseText; var DashboardContent = container.getHTMLById('content'); // getHTMLById is a custom function to emulate getElementById, // which doesn't work outside the document document.getElementById('dashboard').innerHTML = DashboardContent.innerHTML;
An interesting approach. Unfortunately it fails when the content contains images.
What I found out after a few hours of experimenting was, that Explorer Windows now load all images twice, once when they are written into
container.innerHTML and once more when they are written into
Even worse: there seems to be some kind of glitch in the caching or the management of the (normal) http requests for the images. Every once in a while, especially on slow connections, Explorer Windows refuses to show the images in the Dashboard, because (I guess) it's still busy loading them from the server — or something.
I solved the problem by querying the
readyState of all images in
DashboardContent, and only allowing the dashboard to receive the data after all images reported they'd finished loading (
readyState == 'complete'). This seems to work for the moment.
Nonetheless it should be noted that as soon as you load a bit of HTML which includes an
<img> tag into any element's
innerHTML, Explorer starts downloading the images, even if the element is not attached to the visible document. Once you move the bit of HTML to the visible document, Explorer may decide not to show the images because it's still busy loading them — or something.
(Add your own)
* required fields