views:

196

answers:

3

Hi, I'm using jquery's ajax functions to grab a page fragment and display in a section of a page - this fragment includes html and references to external js files.

The program flow looks like this:

Main Page calls -> Fragment page which calls -> various large js files via script tags.

I've turned on the cache option on my initial ajax call so that the fragement page gets cached (no unique IDs appended to the url), however when the fragment is loaded, it appears that jquery rewrites the script urls to include a unix timestamp so that the browser downloads a new copy of the scripts every time. The scripts i'm calling are around 250kb minified and it's really hurting the user experience as the browser locks up whenever they're called. Is this a desired behaviour of jquery? Is there a way to disable the url rewrites?

Many many thanks for your help

A: 
  1. Force the webserver to serve the script with a expire date in the future.

  2. If you use dataType = "script" as an option for jquery ajax the caching will be disabled by default, see http://docs.jquery.com/Ajax/jQuery.ajax#options, try set it manually to "html".

$.ajax({
  type: "GET",
  url: "test.js",
  dataType: "html" // if not set jquery will guess what type it is and disables caching when matching "script"
});
powtac
hi, thanks but I tried that, only the initial request is being called via ajax and that is being cached fine, that ajax request returns content like:<html><script src='http://blah.com/script.js"></script><p>Some html content</p></html>it's the requests to http://blah.com/script.js that are being rewritten as http://blah.com/script.js?_id=3423423423 or similar, preventing caching
Charles Pick
oops, sorry about formatting.
Charles Pick
Does jQUery really append "?_id=007" to the url? Or is it something else, an other script? If I search in the jQuery source I don't find any "_id" also google matches nothing important.
powtac
sorry, it's ?_= not ?_id=
Charles Pick
+2  A: 

Looks like jQuerys's evalScript function is messing you up...

Line 543 of jQuery:

function evalScript( i, elem ) {
    if ( elem.src )
        jQuery.ajax({
            url: elem.src,
            async: false,
            dataType: "script"
        });

   else
        jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );

   if ( elem.parentNode )
       elem.parentNode.removeChild( elem );
}

Here is the breakdown of what happens: The Main Page's JS calls:

$.ajax({
    url:"frag.htm",
    type:"GET",
    success:callBackFunction
})

and GETs frag.htm which contains something like this:

<html><head><script src="test.js"></script></head><body>Content</body></html>

then your callback function is called which probably looks like this:

function callBackFunction(data){
    $("#ajaxContent").html(data); // <- this is the beginning of your problems...
}

When jQuery's html(data) function is called is "cleans" the HTML by removing any script tags and then calls evalScript on each one. evalScript, as you can see, doesn't specify "cache:true" so when it goes through $.ajax cache is null. When cache is null and the dataType is "script" jQuery sets cache=false.

So, to circumvent this problem try this:

function callBackFunction(data){
    var tempAJAX = $.ajax; // save the original $.ajax
        $.ajax=function(s){ // wrap the old $.ajax so set cache to true...
            s.cache=true;
            tempAJAX(s); // call old $.ajax
        }
        $("#ajaxContent").html(data); // insert the HTML and download the <script>s
        $.ajax = tempAJAX; // reset $.ajax to the original.
    }
}

Before we insert the new HTML from "frag.htm" into the Main Page we intercept all calls to $.ajax, modify the object to include cache=true, and then after the script is loaded insert the HTML.

Let me know if you have any questions.

David Murdoch
Fantastic it works, thanks!
Charles Pick
No problem. I'm actually using this in an app I'm putting together now. :o)
David Murdoch
A: 

The value it adds is a unix timestamp. I'm having this issue too. Anyone know how to stop it? The problem occurs if you add a script tag to a page loaded with AJAX.

Anonymous Coward