在JavaScript /浏览器中cachingjquery ajax响应

我想启用JavaScript /浏览器中的ajax响应的caching。

从jquery.ajax文档 :

默认情况下,请求总是发出,但是浏览器可能会从caching中提供结果。 要禁止使用caching的结果,请将caching设置为false。 如果自上次请求后资产尚未修改,请求报告失败,请将ifModified设置为true。

但是,这些地址都不强制caching。

动机:我想在我的初始化函数中放入$.ajax({...})调用,其中一些请求的URL相同。 有时我需要调用其中一个初始化函数,有时我会调用几个函数。

所以,我想要最小化对服务器的请求,如果这个特定的URL已经被加载。

我可以推出我自己的解决scheme(有一些困难!),但我想知道是否有一个标准的方法来做到这一点。

cache:true只适用于GET和HEAD请求。

您可以按照以下方式推出自己的解决scheme:

 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); } 

在这里工作的小提琴

编辑:因为这篇文章成为stream行,这里是一个更好的答案,为那些想要pipe理超时caching,你也不必打扰$ .ajax()中的所有混乱,因为我使用$ .ajaxPrefilter() 。 现在只需设置{cache: true}就足以正确处理caching:

 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); } 

而这里的小提琴 非常小心,不会与$ .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 }); }); }); }); 

小提琴这里有一些问题,我们的cachingID是依赖于json2 lib JSON对象表示。

使用控制台视图(F12)或FireBug查看caching生成的一些日志。

我正在寻找我的phonegap应用程序存储的caching,我发现@TecHunter的答案是伟大的,但使用localCache完成。

我发现并知道localStorage是cachingajax调用返回的数据的另一种方法。 因此,我使用localStorage创build了一个演示,这将帮助其他可能想使用localStorage而不是localCache进行caching的人。

Ajax调用:

 $.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!"); } }); 

将数据存储到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 }; } }); 

如果您要删除localStorage,请使用以下语句:

 localStorage.removeItem("Info"); 

希望它可以帮助别人!

所有现代浏览器都为您提供存储API。 您可以使用它们(localStorage或sessionStorage)来保存您的数据。

所有你需要做的就是收到响应存储到浏览器存储。 然后下一次你find相同的电话,search响应是否已经保存。 如果是,请从那里返回回应; 如果不是打个电话。

Smartjax插件也做类似的事情; 但由于您的要求只是保存通话响应,所以您可以在jQuery ajax成功函数中编写代码以保存响应。 在打电话之前,检查一下响应是否已经保存。

如果我理解你的问题,这里是解决scheme:

  $.ajaxSetup({ cache: true}); 

和特定的电话

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

如果你想要相反(caching特定的调用),你可以在开始时设置为false,特定的调用为true。

老问题,但我的解决scheme有点不同。

我正在编写一个单页的网页应用程序,不断地做出由用户触发的Ajax调用,并使其更加困难,它需要使用除jQuery以外的方法的库(如dojo,native xhr等)。 我为自己的一个库编写了一个插件,以尽可能高效的方式cachingajax请求,这种方式可以在所有主stream浏览器中运行,无论哪个库被用来进行ajax调用。

该解决scheme使用jSQL (由我编写 – 用JavaScript编写的客户端持久化SQL实现,使用indexeddb和其他dom存储方法),并与另一个名为XHRCreep的库(由我编写)捆绑在一起,这是完全重写本机XHR对象。

要实现所有你需要做的是在你的页面中包含插件, 这是在这里 。

有两个选项:

 jSQL.xhrCache.max_time = 60; 

设置分钟的最大时间。 任何比这更老的caching响应都会被重新请求。 默认为1小时。

 jSQL.xhrCache.logging = true; 

设置为true时,模拟XHR调用将显示在控制台中进行debugging。

你可以通过任何给定的页面清除caching

 jSQL.tables = {}; jSQL.persist();