2009
Apr
20

Comparison with XMLHttpRequest()

Advantages

  • Can request a file from anywhere on the net, not just the server your page was loaded from.
  • Works in IE even when ActiveX is turned off (though not when Javascript is turned off).
  • Works with a few older browsers that don't support XMLHttpRequest, like Opera 7 (though not Macintosh versions of IE).

Disadvantages

  • Returned data has to be formatted as Javascript code. XMLHttpRequest() can be used to fetch data in any format, XML, JSON, plain text, or whatever.
  • Can only do GET requests, not POST requests.
  • Whether the request is synchronous or asynchronous is pot luck, depending on the browser. With XMLHttpRequest() you can control this.
  • When fetching JSON data from an untrusted source, there is no possiblity of checking the data before feeding it to the Javascript parser. With XMLHttpRequest() you can parse the data with something like json2.js instead of eval() for secure parsing.

Load Only Once

Example
  1. var script = document.createElement("script");
  2. script.setAttribute("language", "javascript");
  3. script.setAttribute("type", "text/javascript");
  4. script.setAttribute("src", url);
  5. var head = document.getElementsByTagName("head")[0];
  6. head.appendChild(script);

Multiple Loads

Cache

First, you need to worry about caching. Typically, the url you're going to be loading is going to be some kind of CGI program. After all, if the output doesn't vary, why bother loading it more than once? Usually browsers are fairly smart about not caching those, but you might want to take some steps to ensure that the second call doesn't just get you the cached copy of the result of the first call. So the CGI should probably be outputting headers to suppress caching. You might also put extra arguments on the URL, perhaps by keeping a count of the number of times you've called it, and adding a "?count=7" argument onto the end of the URL (where 7 is the current count). This makes the URL different on each call, and further ensures that you won't get a cached copy.

Delete Script

Second, you'll tend to accumulate a lot of script tags in your header. This doesn't necessarily do a whole lot of harm, but it seems sloppy. So you could probably delete them by doing head.removeChild(script). I think you can actually have the callback function do this immediately after loading. Removing the script tag does not undefine functions or variables that were defined by it, so you are done with it the moment it is done loading.

Detect Load Completion

After we have loaded the helper code, we obviously want to call it to start it running. However, we can't just put a call to complete() after the commands above, because the browser may be loading the "myScript.js" file asynchronously, which means that our call may occur before the function has finished (or even started) loading.

Here we set up two different event handlers on the newly created script tag. Depending on the browser, one or the other of these two handlers is supposed to be called when the script has finished loading. The onreadystatechange handler works on IE only. The onload handler works on Gecko browsers and Opera.

The readyState theoretically goes through a series of states:

  • 0 uninitialized
  • 1 loading
  • 2 loaded
  • 3 interactive
  • 4 complete
Example
  1. var HTTPUTILITY = {
  2. getScript: function(url, callback) {
  3. var isLoaded = false;
  4. var script = document.createElement("script");
  5. script.setAttribute("language", "javascript");
  6. script.setAttribute("type", "text/javascript");
  7. script.setAttribute("src", url);
  8. script.onload = script.onreadystatechange = function() {
  9. if (!isLoaded && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) {
  10. isLoaded = true;
  11. if (typeof callback === "function") {
  12. callback();
  13. }
  14. if (this.tagName.toLowerCase() === "script") {
  15. document.getElementsByTagName("head")[0].removeChild(this);
  16. }
  17. }
  18. };
  19. var head = document.getElementsByTagName("head")[0];
  20. head.appendChild(script);
  21. }
  22. };
Example
  1. function complete() {
  2. alert("complete");
  3. }
  4. HTTPUTILITY.getScript("myScript.js", function(){complete();});

View Demo

document.write

Example
  1. document.write('<' + 'script type="text/javascript" src="http://www.lingihuang.com/libraries/library.js"' + '><' + '/script>');

View Demo

Related Posts


回應 (Leave a comment)