Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing the cache time in jquery

if we pass true for cache in $.ajax() the jquery will cache the loaded data, I want to know is there any way to change the cache time for $.ajax() ? for example if ajax requested in 10 minutes the jquery load previous data but if requested after 10 minutes load fresh data.

UPDATE :

We need cache the JSON data, so I should use Ajax in JSON datatype

like image 791
MajAfy Avatar asked May 14 '12 14:05

MajAfy


2 Answers

jQuery doesn't actually cache the requests for you - when you set cache to false, it simply sets some headers and passes a "cache buster" query string variable (e.g., ?_=487262189472) to prevent the browser or any proxies from returning a cached response.

If you want 10 minute caching, you could implement your own fairly easily. E.g.,

var cacheBuster = new Date().getTime();
setInterval(function() {
    cacheBuster = new Date().getTime();
}, 1000 * 60 * 10)

Then simply add that in a query string variable to your requests (e.g., ?_noCache=<cacheBuster>).


Edit: for the sake of making this a more complete solution, here's an example of how you can use the cacheBuster on all jQuery Ajax requests transparently to the actual Ajax call:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    var startChar = options.url.indexOf('?') === -1 ? '?' : '&';
    options.url += startChar + '_noCache=' + cacheBuster;
});
like image 57
jmar777 Avatar answered Oct 21 '22 07:10

jmar777


This sounds like an ideal playground for leveraging jQuery's Deferred object.

There's a great article by Addy Osmani and Julian Aubourg on MSDN here: http://msdn.microsoft.com/en-us/magazine/gg723713.aspx

in short, they have an example there that explains how they cache requests, this request in particular will be cached forever.

var cachedPromises = {};

$.getCachedURL = function( url, callback ) {
    if ( !cachedPromises[ url ] ) {
        cachedPromises[ url ] = $.Deferred(function( defer ) {
            $.get( url ).then( defer.resolve, defer.reject );
        }).promise();
    }
    return cachedPromises[ url ].done( callback );
};

and then resolve the Deferred as such

$.getCachedURL( url ).then( successCallback, errorCallback );

so if you want certain urls to be cached for only a certain time we can modify the existing code and do something along the lines of (note that this is off the top of my head)

var cachedPromises = {};
var cachedTimeouts = {};

$.getCachedURL = function( url, callback, cacheTime) {
    if ( !cachedPromises[ url ] ) {
        cachedPromises[ url ] = $.Deferred(function( defer ) {
            $.get( url ).then( defer.resolve, defer.reject );
        }).promise();
        cachedTimeouts[ url ] = setTimeout(function () {
            clearTimeout(cachedTimeouts[ url ]);
            delete cachedPromises[ url ];
        }, cacheTime);
    }
    return cachedPromises[ url ].done( callback );
};

and using a callback:

var callback = function () {
    console.log('callback', arguments)
}

var cacheTime = 3600;

$.getCachedURL('/dynamic/config', callback, cacheTime).then(function ()
{
    console.log('success', arguments)
}, function ()
{
    console.log('error', arguments)
});

where callback will return the traditional jQuery ajax succes/error arguments data, textStatus and jqXHR

if you want JSON use $.getJSON instead of $.get

$.get( url ).then( defer.resolve, defer.reject );
$.getJSON( url ).then( defer.resolve, defer.reject );

note that you could still just use $.ajax

$.ajax({
    url: url,
    dataType: 'json',
}).then( defer.resolve, defer.reject );
like image 21
Vincent Briglia Avatar answered Oct 21 '22 08:10

Vincent Briglia