Post-AJAX JavaScript calls

3:11 pm CodeStuff

Not too often I post development stuff here, but this is one that’s been bugging me for a few years. For those unfamiliar with it, AJAX is a web technique that involves using a JavaScript call to refresh part of a web page with new content instead of the entire page. The technique is intended to transfer “XML” data (hence the ‘X’ in AJAX), but most times people just use it to move raw HTML markup around. I’ve been wanting to embed JavaScript function calls in the content that I dynamically load on a page, but the AJAX loading technique does not execute any JavaScript in the HTML.

We use AJAX techniques at work a lot, although probably not the way they were initially intended. We build a page that contains some empty DIV, and at some point a JavaScript function will be called to populate this DIV with the result of some arbitrary PHP script. This function will create an XmlHttpRequest object (or an ActiveXObject, if necessary), open a link to some script, send some POST variables, and send the request (lots of web resources to show how this is done).

Here’s a standard AJAX onreadystatechange function to populate a DIV with some code:

objXmlHttp.onreadystatechange=function ()
{
  if (objXmlHttp.readyState==4 || objXmlHttp.readyState=="complete")
    document.getElementById(divID).innerHTML=objXmlHttp.responseText;
}

So, whatever the PHP script “responds” will be dumped into our target DIV. Problem here is that if I happen to embed some JavaScript in the code the PHP script’s response that I might like to have executed, it’s not going to happen.

The solution to this problem, if you absolutely need to execute some arbitrary JavaScript code on coming back from an AJAX call, is to make proper use of AJAX in the first place. Instead of just returning a blob of HTML that can be injected into a DIV, you have to return some formatted XML that contains a tag for your HTML and another tag for your JavaScript (also, in PHP, don’t forget that when you’re returning XML, it’s wise to inform the browser of this by issuing a header('Content-Type: text/xml'); command beforing returning the XML).

<RESPONSE>
  <HTML>some html goes in here</HTML>
  <JS>some JavaScript goes in here</JS>
</RESPONSE>

You can then modify your onreadystatechange function so that it examines the XML that it received, and sends the HTML from the HTML tag to the DIV (as planned), while executing the JavaScript in the JS tag using the eval() JavaScript function.

objXmlHttp.onreadystatechange=function ()
{
  if (objXmlHttp.readyState==4 || objXmlHttp.readyState=='complete')
  {
    if (XMLValueExists(objXmlHttp.responseXML, 'HTML'))
      SetValueFromXML(objXmlHttp.responseXML, divID, 'HTML');
 
    if (XMLValueExists(objXmlHttp.responseXML, 'JS'))
      eval(GetValueFromXML(objXmlHttp.responseXML, 'JS'));
  }
}

(I use a couple of support functions to parse the XML. They involve calling objXmlHttp.getElementsByTagName and some other DOM-wrangling code)

Note that some people frown on using eval() to execute arbitrary JavaScript due to speed and security concerns. First off, execution doesn’t slow down that much (especially with modern PCs), and it’s not like you’re sending 100K of JavaScript to execute (are you?). Furthermore, as far as security is concerned, the same origin policy governing the loading of scripts via JavaScript ensures that the JavaScript that is executed by the eval() statement comes from your website. And if you’re going to argue with me by spouting off stuff about “spoofing”, then you’ve probably got more important things to worry about from a security standpoint. :)

4 Responses
  1. Eugene :

    Date: October 21, 2008 @ 7:54 am

    looking forward for more information about this. thanks for sharing. Eugene

  2. MIke Dunphy :

    Date: October 24, 2008 @ 11:41 pm

    Hello sister, brother in-law, and my sweet little neice. This has nothing to do with what ever jean paul is trying to say with all the coad stuff, because it all looks like jiberish to me….lol!
    But anyways, Greetings From Calgary!!
    Here safe and wanted to say hi, will call you soon to talk but have been real busy with everything, Just wanted to say a quick Hi, So HI!.
    Call you soon
    Mike D

  3. Executing embedded JavaScript after Ajax-call at Some people call me Fredrik :

    Date: October 29, 2008 @ 1:52 pm

    [...] other words, I was fresh out of ideas. I googled around for a solution and found a guy whose solution was to make a “real” Ajax call, returning a piece of XML code consisting of two [...]

  4. Damien :

    Date: January 12, 2009 @ 12:57 pm

    Great help,
    been searching for a workaround for AJAX generated pages for a while.

Leave a Comment

Your comment

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.