Quick tip: XMLHttpRequest and innerHTML

Tweet

XMLHttpRequest is one of modern DHTML’s best kept secrets. If you haven’t encountered it before, it’s a method of making an HTTP call back to the hosting web server without refreshing the whole page – a kind of remote scripting on steroids. Originally a Microsoft extension, it’s been adapted by both the Mozilla browser family and (as of version 1.2) Safari. The Sarissa library discussed previously offers an abstraction layer for the different browsers, or for a more lightweight approach this code from jibbering.com (which makes use of IE’s JScript conditional compilation) works perfectly.

Getting the most out of XMLHttpRequest generally involves using server-side generated XML, which can be retrieved by your JavaScript application, parsed and used in more complex logic. However, for a quick fix the following code will load an HTML fragment from a URL and insert it directly in to a page:


function loadFragmentInToElement(fragment_url, element_id) {
    var element = document.getElementById(element_id);
    element.innerHTML = '<p><em>Loading ...</em></p>';
    xmlhttp.open("GET", fragment_url);
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            element.innerHTML = xmlhttp.responseText;
        }
    }
    xmlhttp.send(null);
}

Call the above function with the URL of the HTML fragment to be inserted and the ID of the element in which it should appear. It relies on the jibbering.com code to set up the xmlhttp variable.

It’s definitely quick and dirty, but it’s also a great quick demonstration of the power of the XMLHttpRequest extension.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • cyngon

    Will that fragment work with an XHTML document?

    For some reason I assumed you couldn’t set the innerHTML property when dealing with an XML document for the same reason you can’t do document.write()s.

  • http://www.phppatterns.com HarryF

    On a related note, looks like Imp (PHP web based email app) is starting to take advantage of XMLHttpRequest – see here.

  • cholmon

    This could make for a fairly easy-to-deploy chat system, with the help of setInterval()

  • Simon

    I used it a bit in the redesign of s1homes as we needed a way of getting the specific location data to the customer without having to preloed the whole thing. Plus I worked out a little trick to get Opera to do a similat thing.

  • neves

    Checkout sarissa, a crossbrowser wrapper for XMLHttpRequest.
    Question: How can I fill a select with rows?

  • Simon Proctor

    The safest way to fill a select is to use the options array. Populating that with new Option objects.
    You can use the DOM to create elements but this apparently cause IE 5 to crash. Which isn’t the baset of things. Well….

  • kyberfabrikken

    for some serious rpc-xml in javascript, have a go at : http://jan.kollhof.net/projects/js/jsolait/doc/jsolait.xhtml

  • http://www.fokjou.nl/ OReason

    I noticed gmail was using it at their registration form. Looks cool.

  • Scott

    As I understand, Safari only supports XMLHTTP as of version 1.2, Netscape as of version 7.0 (and Opera doesn’t at all – at least, not yet.)

    IE/win32 has had it since version 5, I understand they MS were the first to implement this and it was later picked up on by others (even though it hasn’t been officially sanctioned by the W3C, correct me if I’m mistaken.)

  • khlo

    I found I had to change var element = document.getElementById(‘element_id’); to var element = document.getElementById(element_id); to get this to work.

  • Derek

    It appears that Service Pack 2 blocks this kind of thing by default. :(

    I tried opening it in IE 6 on an SP2 computer and got a message that said:

    “To help protect your security, Internet Explorer has restricted this file from showing active content that could access your computer. Click here for options…”

  • rgrajan

    I tried this some time earlier. But when u try to access the site through IP address the XMLHTTPRequest is not working.

  • http://www.tpm-webapplicaties.nl Thomas Ummels

    I have been working on this for a while and have tried different techniques. I guess that if you want this to work cross-browser all the way the safest bet is still working with frames. By using Iframes and create a hidden new one every time you comunicate with the server you can get a long way. (I know old browsers don’t support iframes but you know that frames wrok for every new browser on every platform) I am working on a webiste now where I use it the first time. A demo version can be found at:
    http://www.tpm-webapplicaties.nl/demo/bouwsteenadvies/
    check out:
    http://www.tpm-webapplicaties.nl/demo/bouwsteenadvies/js/js_objClientServerCommunicator_v1.js
    It a first version so all the comments are welcome.

  • Paul

    Another great cross-browser extension to handle XmlHttpRequest:
    http://webfx.eae.net/dhtml/xmlextras/xmlextras.html

  • Daniel Von Fange

    Derek and rgrajan, you can only make XMLHTTPRequest’s to the same site the web pages was loaded from. So if you access your site by it’s ip address, and the script is trying to pull from http://www.example.com, then it won’t run.

  • http://www.niklepage.com NikLP

    Does this not defeat the point of all accessibility issues?

  • http://www.kylehaskins.com blackbird52

    Be careful, I found that you can rewrite the innerHTML of an element once, but if you do it twice it will crash IE on the Mac.

  • sszabo

    I think XML Inclusions
    http://www.w3.org/TR/xinclude/
    can solve the problem.

  • Rick

    Looks real cool. But can you do without using the IE specific innerHTML? … do it using DOM1 or DOM2 instead???

  • Ben Vail

    Hmm.. I’ll stick to IFRAMEs, since I already am using them, save the hassle of compatibility, when IFRAMEs work well with most modern setups..

    If it ain’t broke… ;)

    -Ben [mechg.com/info.php]

  • Richard@Home

    I blogged an alternative method using Javascript/PHP here: http://richardathome.no-ip.com/index.php?article_id=317

  • http://nathanwwong.com someonewhois

    Re: iframes, they make a clicking noise on Windows XP, and it shows as loading – defeats the purpose of making it hidden and unknown (client side) completely, that’s the only problem.

  • Anonymous

    XMLHTML will cache every urls data that has be retrieved when you perfom a “GET”.

    The only way I have found to get around this is to make the url unique each request. This will help prevent any cached data from showing up.

  • Alex

    If you wanna see this stuff in action, look out http://www.xicommunity.ca. We’ve been doing web applications that uses XMLHttpRequest since 5 years and it brings an incredible richness to your web applications.

    On http://www.xicommunity.ca, you will find the XI-Factory tool that allows you to design/generate web application prototypes online!

    You can also get the .NET code when your prototype is approved.

    All this using XMLHttpRequest. Right now it works only with IE but we are looking at making it cross-browsers.

    Enjoy!

  • ben332211

    Aye, if I was wanting it to be hidden and unknown, I’d definately use this… :)

    -Ben

  • Volte

    About the XMLHTML Caching problem. I have encountered this as well. I’ve tried all sorts of stuff. For instance i have a dynamic image, that when the user calls for it, i want an updated image (built from a database) to be displayed however its thinking to much for me, so It loads what it thinks is the correct image. Anyway to say like:

    delete XMLHTML;

    or something?

  • Vg

    I used the code given above for changing the innerHTML of the DIV on my page.
    But I want to do it for multiple DIV on single event.
    But, it dosen’t work if I call it multiple times..
    Please anybody tell me a way to do it.

  • Richard@Home

    Simon, just thought you should know that it looks like someone has ripped your code without giving you a well deserved credit:

    http://www.developertutorials.com/tutorials/php/php-on-fly-050526/page3.html

    Appoligies all round if there IS a credit, but I couldn’t spot it..

  • Anonymous

    Volte Mar:
    var url=pathToImage+’?’+(new Date()).getTime();
    should do the trick

  • Allen

    What about page view tracking? Or serving ad impressions if your page ‘never’ changes?

  • Anonymous

    Vg, you have to redefine the onreadystatechange event handler each time you want to use the object, otherwise it doesn´t work.

  • Pingback: Maheshbabu.Interactive - Web Standards | Design | CSS | Ajax » Blog Archive » Ajax Tutorials, Resources, Links

  • Anonymous

    Same qn as Vg, it doesn’t work I have more than 1 XMLHttpRequest on a page. The thing is when alert messages are used at certain intervals, all the XMLHttpRequest are being processed. Anyone has an idea how to solve this?

    
    
    	// code for Mozilla, etc.
    	if (window.XMLHttpRequest)
    	  {
    	    xmlhttp=new XMLHttpRequest()
    	    
    	    //xmlhttp.onreadystatechange=state_Change
    	    //xmlhttp.open("GET",url,true)
    	    //xmlhttp.send(null)
    	  }
    	// code for IE
    	else if (window.ActiveXObject)
    	  {
    	    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
    	    
    	    //if (xmlhttp)
    	    //{
    	    //xmlhttp.onreadystatechange=state_Change
    	    //xmlhttp.open("GET",url,true)
    	    //xmlhttp.send()
    	    //}	    
    	  }
    		
    	    if (xmlhttp)
    	    {
    	    	//alert("In xmlhttp "+element_id);
    		xmlhttp.open("GET",url,true);
    		////alert("After xml open");
    		
    	    	xmlhttp.onreadystatechange = function() {
    		
    			if (xmlhttp.readyState == 4) 
    			{
    				if (xmlhttp.status == 200)
    				{
    					//alert("XML data OK");
    					element.innerHTML = xmlhttp.responseText;
    				}
    				else
    				{
    					//alert("Problem retrieving XML data "+element_id)
    				}
    			}
    		}	    
    		
    		////alert("Before Request");
    		if (window.XMLHttpRequest)
    	    		xmlhttp.send(null);
    		else
    			xmlhttp.send();
    		////alert("After Request "+element_id);					
    	    }
    
    	}	
    
    
  • fix for caching problem

    I didn’t have the necessary time to read if you founded the sollution to the caching problem, I encontered it myself and fixed it in the following way:
    1. before you make the request with http_request.open
    add a random numer as a query parameter to the url
    a quick example is the following:


    randomnum=Math.random();
    url = url+’&rnd=’+randomnum;
    http_request.open(‘GET’, url, true);

    of cource more validations should be done such as checking if the param you are adding should be added with ? or & at the url.

    I hope this helps.

  • Anonymous

    try setting true to false. don’t use the onreadystatechange when set to TRUE.

  • Anonymous

    gfsd


  • Jay

    Will that fragment work with an XHTML document?
    http://actgeoeng.mod.net.au

  • bl4ck4dd3r

    should this work if the page fetched is .php ?

    all i get is the loading message

  • kyle

    I have a problem further than VG. My code works for multiple divs with one event(thanks to redefining each eventhandler seperately, but sometimes the second div does not refresh(usually if the browser has had no activity for a while, and then the event is triggered).

    Any thoughts?

    Thanks.

  • dhanya

    Hi,

    I have been encountering some problems using POST method. I could not read the data from server side. Pls provide me with example code.

  • shweta

    I have to improve th performance of JavaScript. We have included the calculation part in the script according to Business requirement but it takes more than 4 minutes to load the page. so please can you help out

  • Anonymous
  • immisesnusest

    tests time mashine

  • http://luckyfeeling.org/ RuityCoitty

    I’m new here, just wanted to say hello and introduce myself.