jQuery Cross-Site AJAX Plugin

April 12th, 2007 by Ralf S. Engelschall

It is well known that with the help of a dynamically generated XHTML <script> DOM element one can achieve a portable cross-site variation of an AJAX-style client-server communication as the <script> is not staying under the “same-origin security policy” which restricts the regular AJAX methods. This allows one to load code from a third-party URL in the background.

For this in JavaScript one generates a <script> DOM element with a type attribute set to text/javascript and a src attribute set to the URL of the third-partly URL. That’s it. Well, more or less. But as a jQuery user I wanted this functionality abstracted with a variation of the already existing (plain AJAX) jQuery.getScript() function, which in turn especially allows me to execute a callback function once the script is loaded. And for cleanup and memory leak prevention reasons I wanted that the dynamically generated <script> DOM node is garbage collected automatically, too.

My result is a small jQuery plugin jquery.xsajax.js which provides just this. Find this jQuery plugin in the File Repository area.

13 Responses to “jQuery Cross-Site AJAX Plugin”

  1. Remy Sharp says:

    That plugin doesn’t work in Safari. It looks like you lifted the logic from the jQuery library because I hit a similar problem.

    The reason it doesn’t work in Safari is because the script element doesn’t fire any events when the external library is loaded, and hence listening for the onreadystatechange doesn’t work.

    I wrote an entry on how to get around this problem, but I’m not sure it will be helpful to your plugin without replicating the core test:

    http://remysharp.com/2007/04/12/how-to-detect-when-an-external-library-has-loaded/

  2. Ralf S. Engelschall says:

    Remy Sharp: yes, I had to apply the MSIE special case first and then determined that jQuery core contains a similar thing. And hence I’ve taken over the Safari special case blindly, because I’ve no Safari at hand myself. I’ll look at your workaround. Thanks for the hint.

  3. Ralf S. Engelschall says:

    BTW, does anybody know whether Konqueror/KHTML and Safari/WebKit emit any(!) event at all after loading a <script>?

  4. Ralf S. Engelschall says:

    Ok, I’ve looked deeper into the WebKit sources and the source WebKit/WebCore/html/HTMLTokenizer.cpp shows in the function HTMLTokenizer::notifyFinished() an explicit code which seems to emit the “load” event for the <script> tag. And this line exists already since a longer time in WebKit. So, as long as one uses a not too ancient Safari, I would expect that the “load” event on a <script> fires just fine.

    Unfortunately I’ve no Safari available myself, so can someone with a recent Safari please go to…

    http://trainofthoughts.org/repo/export/jquery/jquery.xsajax.test.html

    …and see whether you see the expected output…

    1. start sequence
    2. end sequence
    3. loaded script 1
    4. loaded script 2
    

    …occurs. If you only see the first two lines, we still have a problem with Safari. If the last two lines also are visible it means the “load” event fired just fine in Safari.

  5. Ralf S. Engelschall says:

    Ok, in the latest version of jquery.xsajax.js I’ve now tried to apply a Safari specific workaround based on two <script> tags. Perhaps someone with Safari can run http://trainofthoughts.org/repo/export/jquery/jquery.xsajax.test.html and tell me what output sequence (”N. xxxxx, N. xxxx”) is visible.

  6. Ralf S. Engelschall says:

    According to responses on jquery-discuss the plugin now also should work in Safari.

  7. traunic says:

    This is a really interesting plugin. I have been a long time JSAN user http://openjsan.org/doc/c/cw/cwest/JSAN/0.10/lib/JSAN.html and yesterday saw the videos of John Resig on yahoo. So this morning I tried jquery for the first time and within an hour had trimmed many of my core functions down to 1/3 their original size. But I was still lacking the On-Demand Javascript http://ajaxpatterns.org/On-Demand_Javascript and lazy loading I am so used to. Instead of using jquery and jsan seperately i was curious how well the two could be integrated. I found a couple require plugins, but they load async which is not so great for lazy loading, they also lack the namespace aspect that jsan provides.

    I took a quick crack at replicating jsan.use and came up w/:

    (function(jq){
    	jq.extend({
    		jsanUse: function(pkg, o){
    			o = jq.extend({
    				includePath: ['/jslib','jslib'],
    				altURL: null,
    				min: false
    			}, o || {});
    			if(o.altURL == null){
    				path = pkg.replace(/\./g, '/');
    				path = (o.min)?path.concat('-min.js'):path.concat('.js');
    			}else{
    				path = o.altURL;
    			}
    			try {
    				classdef = eval(pkg);
    				if (typeof classdef != 'undefined') return classdef;
    			} catch (e) { /* nice try, eh? */ }
    			for (var i = 0; i ...
    
  8. djot says:

    -
    Hi,

    The picture of yourself hides the links in the menu (Firefox v2.0.0.3) … is there no way to set you to :invisible? ;)

    The Cursor is somehow :invisible in this comment textarea, after typing some letters …

    djot
    -

  9. Gary Gurevich says:

    Clever workaround, but in my tests under Safari, there is no guarantee that scripts will be loaded in the order they are created within the DOM. See my test case here:

    http://xorox.net/trax/jsloadtest.html

    Expected output for sequential execution would be 1,2,3,4 but Safari 413.2 shows 3,1,2,4.

  10. apl says:

    Is there any solution for getting *HTML content* from other cross-site url?

  11. Sadaf says:

    Hi!!

    is it freely available?? how can i download the js file?? the svn client asks me for username and password.

    Regards,

  12. Ralf S. Engelschall says:

    It can be downloaded directly from the SVN web frontend: http://trainofthoughts.org/repo/getfile?f=jquery/jquery.xsajax.js&v=35

  13. Sadaf says:

    Thanks :)

Leave a Reply