Ajax functionality without Ajax - OK on IE?

The tiny program below issues a service request in Javascript and receives an asynchronous response produced by php, like Ajax but done differently by using the <script> element. It works on Firefox 3.6 and Opera 10.6, but I am not on Windows now, so cannot test any version of IE and I have no Mac so cannot try Safari.

goodmorning.html


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">
function servicereq( p_script_url ) {
var script = document.createElement( 'script' );
script.src = p_script_url;
script.onload=responsecallback;
document.getElementsByTagName( 'head' )[0].appendChild( script );
}

function responsecallback() { 
 //alert( "goodm="+goodmorning+" goodms="+goodmornings ) ;
 var obj = document.getElementById( 'msgarea' );
 obj.innerHTML = goodmorning;
 var s = goodmornings.split('|') ; // s is now a js array
 obj = document.getElementById( 'msgarea2' );
 obj.innerHTML = s[0]+' and '+s[1] ;
}
</script>
<title>Good Morning</title>
</head>

<body onload="servicereq('goodmorning.php');">
<h5>What do you say in the morning?</h5>
<div id="msgarea"></div>
<h5>and in some other countries?</h5>
<div id="msgarea2"></div>
<h4>OK - Good Morning then...</h4>
</body>
</html>

goodmorning.php


<?php
header( 'Content-Type: text/javascript' );

//  generate the data

$goodmorning = "Good Morning" ;
$goodmornings = "Guten Morgen|Bon Matin" ;

?>
var goodmorning = "<?php echo $goodmorning; ?>";
var goodmornings = "<?php echo $goodmornings; ?>";

This little program is about what to say in the morning and the result is shown in two <div>s msgarea and msgarea2 in the <body>. The servicerequest function requests a js script by 'load-script-from-server-using-URL. The responsecallback function picks up the greetings via js variables goodmorning and goodmornings and puts them into the divs by innerHTML.

So, php has to produce javascript (by default it makes text/html). The content-type php directive header( ‘Content-Type: text/javascript’ ) ensures this.
Then the php code between <?php and ?> is executed and the rest (‘var goodmorning =’ and ‘var goodmornings=’) outside the <? and ?> markers is left as it is. The resulting javascript produced on the server becomes:

var goodmorning = “Good Morning”;
var goodmornings = “Guten Morgen|Bon Matin”;

which is loaded into the script element and ready to use when the script’s onload function fires. The German and French greetings are separated by the vertical bar (|) (my choice) character which makes it very simple to convert it to a js array by a single call of split in responsecallback.

This technique probably has been discovered and rediscovered many times. I recall having read about dynamic script loading some years ago. It offers an alternative when Ajax is not supported for example for older desktop browsers and most current browsers for mobile phones.

Does it work on IE?

To test locally I used: localhost/goodmorning.html
To test on a remote site: rename goodmorning.html to index.html and upload index.html and goodmorning.php.

Yeah, that’s probably the case.

But if you use your remote test site, that’ll give a more realistic representation anyway (network lag etc).

I just tried it using IE8, it didn’t work.

The callback for script.onload is never triggered.
Maybe you could call the callback function from the ‘end’ of the downloaded script file (goodmorning.php)?

Yes, that would work too (can’t test at the moment), but a better check would be:


function tmo() {
    if(typeof goodmorning != 'undefined' ) {
        responsecallback();
    } else {
        setTimeout ( "tmo()" , 100 ) ;
    }
}

Note the ‘typeof’ which is used to test the type of the variable as opposed to the value.

Many thanks Immerse!

Your suggestion placing a call of the responsecallback at the end of
goodmorning.php


var goodmorning = "<?php echo $goodmorning; ?>";
var goodmornings = "<?php echo $goodmornings; ?>";
responsecallback();

worked well for both Firefox and Opera.
While I was writing this you also confirmed it works on IE8! Thanks!

Using setTimeout also works for Firefox and Opera:


function servicereq( p_script_url ) {
var script = document.createElement( 'script' );
script.src = p_script_url;
//script.onload=responsecallback;
document.getElementsByTagName( 'head' )[0].appendChild( script );
setTimeout ( "tmo()" , 100 ) ;
}

function tmo()  // wait until data becomes defined
   {
   if ( goodmorning != 'undefined' )
      {
      responsecallback();
      }
   else
      {
      setTimeout ( "tmo()" , 100 ) ;
      }
   }

Will it work for IE too?

Got access to a Windows XP PC and found it also works for Safari 5 and Google Chrome (downloaded and installed Windows versions of these) accessing my remote test site.

When I tried http://localhost/kentest.html and http://localhost/index.html, with or without the http://, I got error ‘cannot connect to localhost’ for FF,Opera,IE,Safari and Chrome. I assumed this is because there is no Apache installed. Correct? Not my PC so cannot install this.

Just tried it, that’ll work.

If you remove the script.onload=responsecallback; from the html file, and add responsecallback(); to the php file it works on both Firefox and IE on Windows.