Javascript 是否正在从浏览器缓存加载我的页面?
我在页面上有一个“new items”(新项目)徽章,我想在页面从缓存加载后立即更新该徽章(即,当点击“Back”(后退)或“Forward”(前进)返回此页面时)。实现这一目标的最佳方式是什么 设置非常简单。应用程序的布局每8秒查找一次新项目,并相应地更新badge+项目列表Javascript 是否正在从浏览器缓存加载我的页面?,javascript,jquery,browser-cache,jquery-events,browser-history,Javascript,Jquery,Browser Cache,Jquery Events,Browser History,我在页面上有一个“new items”(新项目)徽章,我想在页面从缓存加载后立即更新该徽章(即,当点击“Back”(后退)或“Forward”(前进)返回此页面时)。实现这一目标的最佳方式是什么 设置非常简单。应用程序的布局每8秒查找一次新项目,并相应地更新badge+项目列表 $(function() { setInterval( App.pollForNewItems, 8000 ); }); 当有人离开此页面查看某个项目的详细信息时,可能会发生很多事情。在任何用户查看这些内容之前
$(function() {
setInterval( App.pollForNewItems, 8000 );
});
当有人离开此页面查看某个项目的详细信息时,可能会发生很多事情。在任何用户查看这些内容之前,这些内容都是“新的”,并且该应用程序可能会有多个用户同时使用这些内容(这是用于呼叫中心或支持票证的工作流)
为了确保徽章始终是最新的,我有:
$(window).bind('focus load', function ( event ) {
App.pollForNewItems();
});
..尽管这是可行的,但轮询“加载”上的新项目仅在从缓存加载页面时有用。是否有可靠的跨浏览器方法来判断是否从缓存加载了页面?部分黑客解决方案是在服务器上设置当前时间的var,并在页面顶部设置当前客户端时间的var。如果它们之间的差异超过某个阈值(1分钟?),则可以假定这是一个缓存页面加载 示例JS(在服务器端使用ASP.Net语法):
var serverTime=新日期(“”);
var pageStartTime=Date.UTC(新日期());
var isCached=serverTime60000;
或者,在客户端使用cookie(假设启用了cookie),您可以为页面的当前版本检查具有唯一密钥的cookie。如果不存在cookie,则为其编写cookie,在任何其他页面访问中,cookie的存在表明它正在从缓存加载
例如(假设有一些cookie助手函数可用)
var uniqueKey='';
var currentCookie=getCookie(uniqueKey);
var isCached=currentCookie!==无效的
setCookie(uniqueKey)//Cookie应设置为过期
//在合理的时间范围内
我个人会为每个元素设置包含项目id的数据属性
即
- 某些项目
- 其他一些项目
- 另一个
您的App.pollForNewItems
函数将获取第一个元素的数据项id
属性(如果最新的元素是第一个),并将其与原始请求一起发送到服务器
然后,服务器将只返回项目WHERE id>…
,然后您可以将这些项目预先添加到列表中
我仍然不明白为什么您想知道浏览器是否有页面的缓存版本
另外,是否有理由绑定到load
而不是ready
- 基督教徒
Cache-control: no-cache
Cache-control: no-store
Pragma: no-cache
Expires: 0
特别是,Cache control:no store
非常有趣,因为它告诉浏览器根本不要将页面存储在内存中,这样可以防止在按下后退/前进按钮时加载过时的页面
如果您改为这样做,您就不必在页面加载时轮询数据。导航计时现在在大多数浏览器中(ie9+) 回答得好: 您还可以使用导航计时来详细测量网络延迟 这是一篇好文章: 例如,如果fetchStart和responseStart之间的时间差很小,则该页是从缓存加载的
通过stewe我不会特别依赖于服务器和客户端的同步:/问题在于,您假设时钟是同步的。JS中的时间是由本地计算机的时间决定的,这可能与服务器的时间有很大差异。@Matchu,同步是一个棘手的问题,不会生成另一个对服务器的调用来计时延迟。很有趣!虽然这在我的情况下确实有效,但我仍然想知道是否有一个跨浏览器的解决方案来确定页面是否确实是从缓存加载的。这在JS中是可能的吗?@Blackcoat-你可以用cookies做类似的事情。。。我会看看是否能给出一个例子。Christian,这是一个很好的建议,尽管应用程序已经完全按照您所描述的做了(尽管时间戳被比较而不是ID)。至于使用“load”而不是“ready”,我还想绑定到“focus”事件,并且我想保持代码的干爽Ready'是由jQuery构造的人工事件,它只能绑定到文档。如果尝试
$(document.bind('focus ready',{…})
,则不会为“focus”事件触发处理程序。对于从缓存加载的页面,“ready”和“load”事件之间的时间差应该可以忽略不计,“load”在这里就可以了。我甚至没有想到缓存头!只要性能不受影响,这可能是正确的方法(我想确保这不会迫使UA总是下载应该在应用程序中缓存的共享资产,例如JS、CSS、图像)。虽然这是一个解决问题的方法,但我仍然很好奇您是否可以检测到页面是否通过JS从缓存加载。有什么想法吗?我不知道是否有办法判断页面是否来自缓存@不过,jball在检测页面呈现日期方面的想法是正确的。究竟在哪里设置这些变量?这个解决方案在Firefox中似乎不起作用?Firefox也有解决方法吗?这是解决我问题的最好办法@Ralph它在macOS 10.13上的Firefox61中为我工作
var uniqueKey = '<%= SomeUniqueValueGenerator() %>';
var currentCookie = getCookie(uniqueKey);
var isCached = currentCookie !== null;
setCookie(uniqueKey); //cookies should be set to expire
//in some reasonable timeframe
<ul>
<li data-item-id="123">Some item.</li>
<li data-item-id="122">Some other item.</li>
<li data-item-id="121">Another one..</li>
</ul>
Cache-control: no-cache
Cache-control: no-store
Pragma: no-cache
Expires: 0
if (!!window.performance && window.performance.navigation.type === 2) {
// page has been hit using back or forward buttons
} else {
// regular page hit
}