Caching jQuery ajax response in javascript / browser

I would like to enable ajax response caching in javascript / browser.

From jquery.ajax docs :

By default, requests are always issued, but the browser can serve results from the cache. To prohibit the use of cached results, set the cache to false. To make the request report an error if the asset has not been modified since the last request, set ifModified to true.

However, none of these addresses causes caching.

Motivation: I want to put calls to $.ajax({...}) in my initialization functions, some of which request the same URL. Sometimes I need to call one of these initialization functions, sometimes I call several.

So, I want to minimize server requests if this URL is already loaded.

I could curtail my decision (with some difficulty!), But I would like to know if there is a standard way to do this.

+65
javascript jquery browser ajax caching
Jun 14 '13 at 8:30
source share
5 answers

cache:true only works with GET and HEAD requests.

You can overturn your own solution, as you said, something like this:

 var localCache = { data: {}, remove: function (url) { delete localCache.data[url]; }, exist: function (url) { return localCache.data.hasOwnProperty(url) && localCache.data[url] !== null; }, get: function (url) { console.log('Getting in cache for url' + url); return localCache.data[url]; }, set: function (url, cachedData, callback) { localCache.remove(url); localCache.data[url] = cachedData; if ($.isFunction(callback)) callback(cachedData); } }; $(function () { var url = '/echo/jsonp/'; $('#ajaxButton').click(function (e) { $.ajax({ url: url, data: { test: 'value' }, cache: true, beforeSend: function () { if (localCache.exist(url)) { doSomething(localCache.get(url)); return false; } return true; }, complete: function (jqXHR, textStatus) { localCache.set(url, jqXHR, doSomething); } }); }); }); function doSomething(data) { console.log(data); } 

Working fiddle here

EDIT: As this post becomes popular, here is an even better answer for those who want to manage the timeout timeout, and you also don't need to worry about all the mess in $. ajax () since I am using $. ajaxPrefilter () . Now just setting {cache: true} enough to properly handle the cache:

 var localCache = { /** * timeout for cache in millis * @type {number} */ timeout: 30000, /** * @type {{_: number, data: {}}} **/ data: {}, remove: function (url) { delete localCache.data[url]; }, exist: function (url) { return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout); }, get: function (url) { console.log('Getting in cache for url' + url); return localCache.data[url].data; }, set: function (url, cachedData, callback) { localCache.remove(url); localCache.data[url] = { _: new Date().getTime(), data: cachedData }; if ($.isFunction(callback)) callback(cachedData); } }; $.ajaxPrefilter(function (options, originalOptions, jqXHR) { if (options.cache) { var complete = originalOptions.complete || $.noop, url = originalOptions.url; //remove jQuery cache as we have our own localCache options.cache = false; options.beforeSend = function () { if (localCache.exist(url)) { complete(localCache.get(url)); return false; } return true; }; options.complete = function (data, textStatus) { localCache.set(url, data, complete); }; } }); $(function () { var url = '/echo/jsonp/'; $('#ajaxButton').click(function (e) { $.ajax({ url: url, data: { test: 'value' }, cache: true, complete: doSomething }); }); }); function doSomething(data) { console.log(data); } 

And the violin here is CAUTION not working with $ .Deferred

Here is a working but erroneous implementation working with deferred:

 var localCache = { /** * timeout for cache in millis * @type {number} */ timeout: 30000, /** * @type {{_: number, data: {}}} **/ data: {}, remove: function (url) { delete localCache.data[url]; }, exist: function (url) { return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout); }, get: function (url) { console.log('Getting in cache for url' + url); return localCache.data[url].data; }, set: function (url, cachedData, callback) { localCache.remove(url); localCache.data[url] = { _: new Date().getTime(), data: cachedData }; if ($.isFunction(callback)) callback(cachedData); } }; $.ajaxPrefilter(function (options, originalOptions, jqXHR) { if (options.cache) { //Here is our identifier for the cache. Maybe have a better, safer ID (it depends on the object string representation here) ? // on $.ajax call we could also set an ID in originalOptions var id = originalOptions.url+ JSON.stringify(originalOptions.data); options.cache = false; options.beforeSend = function () { if (!localCache.exist(id)) { jqXHR.promise().done(function (data, textStatus) { localCache.set(id, data); }); } return true; }; } }); $.ajaxTransport("+*", function (options, originalOptions, jqXHR, headers, completeCallback) { //same here, careful because options.url has already been through jQuery processing var id = originalOptions.url+ JSON.stringify(originalOptions.data); options.cache = false; if (localCache.exist(id)) { return { send: function (headers, completeCallback) { completeCallback(200, "OK", localCache.get(id)); }, abort: function () { /* abort code, nothing needed here I guess... */ } }; } }); $(function () { var url = '/echo/jsonp/'; $('#ajaxButton').click(function (e) { $.ajax({ url: url, data: { test: 'value' }, cache: true }).done(function (data, status, jq) { console.debug({ data: data, status: status, jqXHR: jq }); }); }); }); 

TELL HERE Some problems, our cache identifier depends on the representation of the json2 lib JSON object.

Use the console view (F12) or FireBug to view some of the cache-generated logs.

+110
Jun 14 '13 at 8:45
source share

I was looking for caching for my mobile phone app store, and I found @TecHunter answer, which is fine, but using localCache .

I found and found out that localStorage is another alternative to caching the data returned by an ajax call. So, I created one demo using localStorage , which will help other users who might want to use localStorage instead of localCache for caching.

Ajax Call:

 $.ajax({ type: "POST", dataType: 'json', contentType: "application/json; charset=utf-8", url: url, data: '{"Id":"' + Id + '"}', cache: true, //It must "true" if you want to cache else "false" //async: false, success: function (data) { var resData = JSON.parse(data); var Info = resData.Info; if (Info) { customerName = Info.FirstName; } }, error: function (xhr, textStatus, error) { alert("Error Happened!"); } }); 

To save data to localStorage:

 $.ajaxPrefilter(function (options, originalOptions, jqXHR) { if (options.cache) { var success = originalOptions.success || $.noop, url = originalOptions.url; options.cache = false; //remove jQuery cache as we have our own localStorage options.beforeSend = function () { if (localStorage.getItem(url)) { success(localStorage.getItem(url)); return false; } return true; }; options.success = function (data, textStatus) { var responseData = JSON.stringify(data.responseJSON); localStorage.setItem(url, responseData); if ($.isFunction(success)) success(responseJSON); //call back to original ajax call }; } }); 

If you want to remove localStorage, use the following statement wherever you want:

 localStorage.removeItem("Info"); 

Hope this helps others!

+8
Jun 05 '15 at 5:55
source share

All modern browsers provide you with apis for storage. You can use them (localStorage or sessionStorage) to save your data.

All you have to do is, after receiving the response, store it in the browser repository. Then the next time you find the same call, do a search if the answer is already saved. If so, return the answer from there; if you do not make a new call.

Smartjax plugin also performs similar actions; but since your requirement just saves the answer to the call, you can write your code inside your jQuery ajax success function to save the answer. And before calling just check if the answer is saved.

+4
Mar 14 '15 at 19:50
source share

If I understood your question, here is the solution:

  $.ajaxSetup({ cache: true}); 

and for specific challenges

  $.ajax({ url: ..., type: "GET", cache: false, ... }); 

If you want the other way around (cache for specific calls), you can set false at the beginning and true for specific calls.

+3
Jun 14 '13 at 8:35
source share

Old question, but my solution is a little different.

I wrote a one-page web application that constantly called ajax calls that the user called, and for even more difficulty libraries were needed that used methods other than jquery (e.g. dojo, native xhr, etc.). I wrote a plugin for one of my own libraries for caching ajax requests as much as possible so that it works in all major browsers, regardless of which libraries were used to call ajax.

The solution uses jSQL (written by me - a permanent client-side SQL implementation written in javascript that uses indexeddb and other dom storage methods), and bundled with another library called XHRCreep (written by me), which is a complete rewrite of its own XHR object .

To implement all you have to do is enable the plugin on your page, which is here .

There are two options:

 jSQL.xhrCache.max_time = 60; 

Set the maximum age in minutes. All cached responses that are older than this are requested again. The default value is 1 hour.

 jSQL.xhrCache.logging = true; 

If set to true, for debugging the console will display false XHR calls.

You can clear the cache on any page through

 jSQL.tables = {}; jSQL.persist(); 
0
Dec 29 '16 at 20:17
source share



All Articles