我有一段JS的,做一个AJAX请求到我的服务器,它返回一些JSON缓存从AJAX数据。它看起来像这样:返回通过延迟回调
$.ajax({
dataType: 'json',
type: 'GET',
localCache: true,
cacheTTL: 6,
url: url
}).fail(function(jqXHR, textStatus, something) {
//Display error message
}).done(function(data) {
//Do stuff with the data
});
现在,我想什么做的是缓存使用localStorage的客户端的JSON,因此,如果缓存足够新鲜,请求永远不会实际发送,并且缓存被用来代替。我一直在使用Paul Irish的ajax-localstorage-cache插件来做到这一点,但不幸的是,它不支持延迟回调,所以我尽我所能来修改它,以便它可以。
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
// Cache it ?
if (!Modernizr.localstorage || !options.localCache) return;
var hourstl = options.cacheTTL || 5;
var cacheKey = options.cacheKey || options.url.replace(/jQuery.*/,'') + options.type + options.data;
// if there's a TTL that's expired, flush this item
var ttl = localStorage.getItem(cacheKey + 'cachettl');
if (ttl && ttl < +new Date()){
localStorage.removeItem(cacheKey);
localStorage.removeItem(cacheKey + 'cachettl');
ttl = 'expired';
}
var value = localStorage.getItem(cacheKey);
if (value) {
//In the cache? So get it, apply done callback & abort the XHR request
// parse back to JSON if we can.
if (options.dataType.indexOf('json') === 0) value = JSON.parse(value);
//Pass value back to the done callback somehow...
// Abort is broken on JQ 1.5 :(
jqXHR.abort();
} else {
$.Deferred(function(defer) {
//If it not in the cache, we change the done callback, just put data on localstorage and after that apply the initial callback
if (jqXHR.done) {
jqXHR.realdone = jqXHR.done;
}
jqXHR.done(function(data) {
var strdata = data;
if (options.dataType.indexOf('json') === 0) strdata = JSON.stringify(data);
// Save the data to localStorage catching exceptions (possibly QUOTA_EXCEEDED_ERR)
try {
localStorage.setItem(cacheKey, strdata);
// store timestamp
if (! ttl || ttl === 'expired') {
localStorage.setItem(cacheKey + 'cachettl', +new Date() + 1000 * 60 * 60 * hourstl);
}
} catch (e) {
// Remove any incomplete data that may have been saved before the exception was caught
localStorage.removeItem(cacheKey);
localStorage.removeItem(cacheKey + 'cachettl');
if (options.cacheError) options.cacheError(e, cacheKey, strdata);
}
if (jqXHR.realdone) jqXHR.realdone(defer.resolve);
}).fail(defer.reject)
}).promise(jqXHR);
}
});
我遇到的问题是,我似乎无法弄清楚如何获得缓存值回原来done
回调。如果我做jqXHR.abort()
,fail
回调将会运行,如果我不放弃,那么它只会正常执行请求。
我在做一些非常错误的事情吗?如果是这样,那么更聪明的方法是什么?如果没有,我怎样才能将缓存的值返回到完成的回调(或至少让它回到失败回调)?
您可能需要重新链接'$ .ajax'本身;尽管如此,浏览器缓存不应该足够好吗? – 2013-02-19 13:29:58
对于这个特定的用例,浏览器缓存可能足够好。但是我们希望将其用于其他类型的缓存,也可能不会。 – 2013-02-19 13:53:30
你是说在安装ajax-localstorage-cache插件时,'$ .ajax()'不返回Promise?如果没有,那么你需要联系插件的作者。 – 2013-02-20 02:16:34