cam*_*mil 92 javascript browser ajax jquery caching
我想在javascript/browser中启用ajax响应的缓存.
默认情况下,始终发出请求,但浏览器可能会从其缓存中提供结果.要禁止使用缓存的结果,请将cache设置为false.如果自上次请求后资产未被修改,则导致请求报告失败,请将ifModified设置为true.
但是,这些都不会强制缓存.
动机:
我想$.ajax({...})在我的初始化函数中调用,其中一些函数请求相同的url.有时我需要调用其中一个初始化函数,有时我会调用几个函数.
因此,如果已经加载了特定的URL,我想最小化对服务器的请求.
我可以推出自己的解决方案(有些困难!),但我想知道是否有一种标准的方法可以做到这一点.
Tec*_*ter 140
cache:true 仅适用于GET和HEAD请求.
您可以按照以下方式说出您自己的解决方案:
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);
}
Run Code Online (Sandbox Code Playgroud)
编辑:随着这篇文章变得流行,对于那些想要管理超时缓存的人来说,这是一个更好的答案,你也不必为$ .ajax()中的所有混乱而烦恼,因为我使用$ .ajaxPrefilter().现在只需设置{cache: true}即可正确处理缓存:
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);
}
Run Code Online (Sandbox Code Playgroud)
这里的小提琴 小心翼翼,不与$ .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
});
});
});
});
Run Code Online (Sandbox Code Playgroud)
这里 有一些问题,我们的缓存ID取决于json2 lib JSON对象表示.
使用控制台视图(F12)或FireBug查看缓存生成的某些日志.
imm*_*odi 11
我正在为我的phonegap应用程序存储寻找缓存,我找到了@TecHunter的答案,这很好但是完成了使用localCache.
我发现并且知道localStorage是缓存ajax调用返回的数据的另一种选择.所以,我创建了一个演示,使用localStorage它可以帮助其他可能想要使用localStorage而不是localCache用于缓存的人.
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!");
}
});
Run Code Online (Sandbox Code Playgroud)
要将数据存储到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
};
}
});
Run Code Online (Sandbox Code Playgroud)
如果要删除localStorage,请在任何位置使用以下语句:
localStorage.removeItem("Info");
Run Code Online (Sandbox Code Playgroud)
希望它能帮到别人!
小智 6
如果我理解你的问题,这是解决方案:
$.ajaxSetup({ cache: true});
Run Code Online (Sandbox Code Playgroud)
和特定的电话
$.ajax({
url: ...,
type: "GET",
cache: false,
...
});
Run Code Online (Sandbox Code Playgroud)
如果您想要相反(特定调用的缓存),您可以在开头设置false,为特定调用设置true.