我想在javascript/browser中启用ajax响应的缓存
从jquery.ajax文档:
默认情况下,始终发出请求,但浏览器可能会提供服务
结果将从其缓存中删除。若要禁止使用缓存结果,请设置
缓存设置为false。使请求报告失败,如果资产
自上次请求后未修改,请将ifModified设置为true
但是,这两种方法都不能强制缓存地址
动机:
我想将$.ajax({…})调用放入我的初始化函数中,其中一些函数请求相同的url。有时我需要调用其中一个初始化函数,有时我调用几个
因此,如果特定url已加载,我希望尽量减少对服务器的请求。
我可以推出我自己的解决方案(有些困难!),但我想知道是否有一种标准的方法可以做到这一点
cache:true仅适用于GET和HEAD请求
您可以按照以下思路推出自己的解决方案:
var localCache={
数据:{},
删除:函数(url){
删除localCache.data[url];
},
存在:函数(url){
返回localCache.data.hasOwnProperty(url)&;localCache.data[url]!==null;
},
获取:函数(url){
log('正在缓存中获取url'+url);
返回localCache.data[url];
},
set:函数(url、缓存数据、回调){
localCache.remove(url);
localCache.data[url]=cachedData;
if($.isFunction(callback))回调(cachedData);
}
};
$(函数(){
var url='/echo/jsonp/';
$(“#ajaxButton”)。单击(函数(e){
$.ajax({
url:url,
数据:{
测试:“值”
},
是的,
beforeSend:函数(){
if(localCache.exist(url)){
doSomething(localCache.get(url));
返回false;
}
返回true;
},
完成:函数(jqXHR,textStatus){
set(url、jqXHR、doSomething);
}
});
});
});
功能剂量测量(数据){
控制台日志(数据);
}
在这里拉小提琴
编辑:随着这篇文章越来越流行,对于那些想要管理超时缓存的人来说,这里有一个更好的答案,你也不必在我使用$.ajaxPrefilter()时为$.ajax()中的所有混乱而烦恼。现在只要设置{cache:true}就足以正确处理缓存:
var localCache={
/**
*缓存超时(毫秒)
*@type{number}
*/
超时:30000,
/**
*@type{{}:编号,数据:{}
**/
数据:{},
删除:函数(url){
删除localCache.data[url];
},
存在:函数(url){
return!!localCache.data[url]&;((new Date().getTime()-localCache.data[url]。)<;localCache.timeout);
},
获取:函数(url){
log('正在缓存中获取url'+url);
返回localCache.data[url].data;
},
set:函数(url、缓存数据、回调){
localCache.remove(url);
localCache.data[url]={
_:新建日期().getTime(),
数据:cachedData
};
if($.isFunction(callback))回调(cachedData);
}
};
$.ajaxPrefilter(函数(选项、原始选项、jqXHR){
if(options.cache){
var complete=originalOptions.complete | |$.noop,
url=originalOptions.url;
//删除jQuery缓存,因为我们有自己的localCache
options.cache=false;
options.beforeSend=函数(){
if(localCache.exist(url)){
完成(localCache.get(url));
返回false;
}
返回true;
};
options.complete=函数(数据、文本状态){
localCache.set(url、数据、完成);
};
}
});
$(函数(){
var url='/echo/jsonp/';
$(“#ajaxButton”)。单击(函数(e){
$.ajax({
url:url,
数据:{
测试:“值”
},
是的,
完成:doSomething
});
});
});
功能剂量测量(数据){
控制台日志(数据);
}
这里的小提琴要小心,不要使用美元。递延
以下是一个正在运行但有缺陷的实现,用于延迟:
var localCache={
/**
*缓存超时(毫秒)
*@type{number}
*/
超时:30000,
/**
*@type{{}:编号,数据:{}
**/
数据:{},
删除:函数(url){
删除localCache.data[url];
},
存在:函数(url){
return!!localCache.data[url]&;((new Date().getTime()-localCache.data[url]。)<;localCache.timeout);
},
获取:函数(url){
log('正在缓存中获取url'+url);
返回localCache.data[url].data;
},
set:函数(url、缓存数据、回调){
localCache.remove(url);
localCache.data[url]={
_:新建日期().getTime(),
数据:cachedData
};
if($.isFunction(callback))回调(cachedData);
}
};
$.ajaxPrefilter(函数(选项、原始选项、jqXHR){
if(options.cache){
//这是缓存的标识符。可能有更好、更安全的ID(这取决于此处的对象字符串表示)?
//在$.ajax调用中,我们还可以在originalOptions中设置一个ID
var id=originalOptions.url+JSON.stringify(originalOptions.data);
options.cache=false;
options.beforeSend=函数(){
如果(!localCache.exist(id)){
jqXHR.promise().done(函数(数据、文本状态){
set(id,data);
});
}
返回true;
};
}
});
$.ajaxTransport(“+*”,函数(选项、原始选项、jqXHR、标题、completeCallback){
//这里也一样,要小心,因为options.url已经通过jQuery处理
var id=originalOptions.url+JSON.stringify(originalOptions.data);
options.cache=false;
if(localCache.exist(id)){
返回{
发送:函数(标题、completeCallback){
completeCallback(200,“OK”,localCache.get(id));
},
中止:函数(){
/*中止代码,我想这里不需要什么*/
}
};
}
});
$(函数(){
var url='/echo/jsonp/';
$(“#ajaxButton”)。单击(函数(e){
$.ajax({
url:url,
数据:{
测试:“值”
},
缓存:真
}).完成(功能(数据、状态、jq){
console.debug({
数据:数据,
状态:状态,
jqXHR:jq
});
});
});
});
在这里拉小提琴
在某些问题上,我们的缓存ID依赖于json2 lib JSON对象表示
使用控制台视图(F12)或FireBug查看缓存生成的一些日志