loadJS_XHR is a small function that loads JavaScript code dynamically using XMLHTTPRequest to link to the server (hence the 'XHR' suffix). This means that, unlike loadJS_STH, it can download code only from the originating domain, but that it can do so synchronously.
While this blocks further execution until the transaction has completed (successfully or not), it obviates the call-back technique described in the page that covers loadJS_STH, thus simplifying design considerably, and thereby allowing certain applications that would otherwise be awkward or even impracticable to implement.
On retrieval of the code, the function appends it to the head element's collection of script elements, whereupon the browser evaluates the code into global scope. Given this, it does not use the eval function, although the usual caveats relating to that JavaScript-feature still apply. This is because the server that sends the code could be a proxy that retrieves the code from an untrustworthy source before passing it to the client.
Note that loadJS_XHR relies upon the XMLHTTPRequest library that also forms part of the libraries that are available from this site. Alternatively, you can use it with an XHR library of your choice, as long as you can pass an object that implements the doTxn method of the XHRWrapper type. This tutorial assumes that you are using the XHR library that is available here, or another library that implements the doTxn method faithfully.
Using loadJS_XHR
Passing an Error Handler
Product Version: 1.1
Tutorial Version: 2.0
API Doc. Version: 2.0
Before making any calls to loadJS_XHR, your code must import the XHR library that you are using. Beyond this, the simplest way of calling loadJS_XHR is to pass just the URL of the desired JavaScript code as the first argument, and an XHRWrapper.
Example 1 shows this, where the XHRWrapper is generated inline at the point of loadJS_XHR's invocation (although the object could be instantiated discretely before being passed in by reference). Assuming a successful transaction, the interpreter returns from loadJS_XHR, and proceeds to execute sayIt, which is now a member of the Global object.
// Example 1
//
// Contents of MyLib.js
//
// function sayIt () { alert ("Hello World"); }
//
//
loadJS_XHR ("MyLib.js", XHRFactory.createXHRWrapper ());
sayIt ();
--------------------------------------
Output:
Hello World
loadJS_XHR also accepts, as its third argument, a reference to a user-defined error-handling function. This is invoked in two cases.
The first is where loadJS_XHR completes the transaction with the server successfully, but the JavaScript retrieved is not well-formed. Here, no interpreter will be able to evaluate the code into Global scope, yet most will not raise a catchable exception. However, browsers such as Google Chrome do, in which case loadJS_XHR will catch that exception, and will invoke any error handler that you have provided.
The second case is where more fundamental errors arise, such as a missing file, or outright server-failure. In those cases, loadJS_XHR will catch the error condition that the underlying XHRWrapper detects, and will call any error handler that you have provided.
In the case of Example 2, an error condition (that is detected) will cause the error handler to execute, which simply reports the situation.
However, following that, the interpreter will return from the call to loadJS_XHR, and will attempt to call sayIt - an attempt that will fail. Obviously, in these cases, production code should take rather more substantial steps in response to such errors, such as to throw an exception, or even define stub implementations of the missing resource(s) on the hoof.
// Example 2
// Non-Existent.js really does not exist.
function OnLibLoadError (Message) // In the case of syntax errors in the downloaded code,
{ // browsers such as Google Chrome wil execute this.
alert (Message);
}
loadJS_XHR ("Non-Existent.js", XHRFactory.createXHRWrapper (), OnLibLoadError); // Given that loading fails here,
// sayIt will not exist, and
sayIt (); // execution will fail here
--------------------------------------
Output:
Unable to retrieve library from server - XHR Object.status : 404
sayIt is not defined