提问人:Jamey McElveen 提问时间:11/4/2008 更新时间:6/1/2023 访问量:17911
如何使用 JavaScript 来检测我是否在缓存的页面上
How can I use JavaScript to detect if I am on a cached page
答:
一种方法是在页面中包含页面的生成时间,然后使用一些 javascript 将本地时间与页面生成时间进行比较。如果时间相差一个阈值,则页面来自缓存。问题在于,如果客户端计算机的时间设置不正确,尽管您可以通过让客户端在生成页面的请求中包含其当前系统时间,然后将该值发送回客户端来解决这个问题。
评论
不是直接的,某些浏览器可能有一些自定义命令。
有一种解决方法可以满足您的要求。使用 cookie 存储第一次访问,然后使用 META HTTP-EQUIV 设置文件缓存的时间长度 ()。如果当前时间在从 到 的时间段内,则将其视为从缓存加载。缓存过期后,重置 cookie 时间。timestamp
cacheLength
timestamp
timestamp+cacheLength
使用 XmlHttpRequest,可以拉出当前页面,然后检查响应的 http 标头。
最好的情况是只执行 HEAD 请求,然后检查标头。
有关执行此操作的一些示例,请查看 http://www.jibbering.com/2002/4/httprequest.html
评论
我从上面给出的答案“丹尼尔”开始,但我担心在缓慢的连接中,我可能会遇到一些延迟问题。
这是最终对我有用的解决方案。在服务器端,我添加了一个 cookie refCount 并将其值设置为 0。在 javascript 中加载文档时,我首先检查 refCount,然后递增它。当检查 refCount 是否大于 1 时,我知道页面已缓存。所以对于这个来说,这就像一个魅力。
谢谢你们引导我找到这个解决方案。
评论
onLoad
虽然这个问题已经有 4 年了。我以为我会使用 jQuery 和 History 插件添加我的 2 美分。
$(document).ready(function()
{
$('body').append('<div class="is_cached"></div>');
});
History.Adapter.bind(window,'statechange',function(){
if($('.is_cached').length >= 1)
{
alert('this page is cached');
}
});
首次加载文档时。将附加一个新div.is_cached。加载缓存页面时,没有兼容的方法来执行 javascript,但您可以监视历史记录更改。当历史记录更改且div.is_cached存在时,用户正在查看缓存的分页。
评论
使用新的资源计时级别 2 规范,可以使用 transfer size 属性来检查页面是否从缓存加载:
var isCached = performance.getEntriesByType("navigation")[0].transferSize === 0;
- 产品规格: https://www.w3.org/TR/resource-timing-2/#dom-performanceresourcetiming-transfersize
- 浏览器支持:https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming#Browser_compatibility
- 请注意,在撰写本文时,它显示 Safari 不支持,而实际上最新版本支持。
评论
pnt.transferSize === 0 && pnt.type === 'back_forward'
- 在创建时将唯一数据添加到服务器上的页面。例如,随机数或创建时间:
window.rand = {{ rand() }}
- 使用本地存储将 url 与数字一起保存,并在需要时稍后进行比较:
reloadIfCached() {
var cached = localStorage.getItem(window.location.href) == window.rand;
if (cached) {
window.location.reload();
}
localStorage.setItem(window.location.href, window.rand);
}
尝试 API,它将返回所有网络资源的每个阶段时间及其 ,如下所示:performance.getEntriesByType('resource')
name
type
上面的屏幕截图显示,我们得到的文件名为 download total 是 925 (ms),它的类型是 .https://www.google.com/xjs/_/js/k=xjs...
duration
script
因此,我们可以根据其 来检测某些文件是否命中缓存,并进行过滤,或者我们想要关注:duration
type
name
const includeFileTypes = [
'script',
// 'css',
// 'img',
]
const includeFileNames = [
'yourTargteFileName.js',
]
function getFileNameFromURL(url) {
return url?.match(/[^\\/]+(?!.*\/)/)?.[0]
}
const getResourceTiming = () => {
const resources = performance
.getEntriesByType('resource')
.filter(({ initiatorType }) => {
return includeFileTypes.includes(initiatorType)
})
// .filter(({ name }) => {
// return includeFileNames.includes(getFileNameFromURL(name))
// });
return resources.map(
({
name,
// redirectEnd,
// redirectStart,
// domainLookupEnd,
// domainLookupStart,
// connectEnd,
// connectStart,
// secureConnectionStart,
responseEnd,
responseStart,
// fetchStart,
// requestStart,
startTime,
duration,
}) => ({
name: getFileNameFromURL(name),
startTime: parseInt(startTime),
endTime: parseInt(responseEnd - responseStart),
duration: parseInt(duration),
}),
);
};
function getHitCacheFiles(allTargetResources) {
return allTargetResources?.filter(({name, duration}) => {
if (duration < 20) {
console.log(`Hit Cache: ${name}`)
return true
} else {
console.log(`Not Hit Cache: ${name}`)
return false
}
})
}
const allTargetResources = getResourceTiming()
console.table(getHitCacheFiles(allTargetResources))
演示
它将打印:
它还与 DevTool Network 面板保持一致:
getEntriesByType('resource')
用法比 简单,它不需要额外的 HTTP 头transferSize
Timing-Allow-Origin: https://yoursite.com
评论