哎我真蠢-service worker与nav页爆炸
由于事件发生在本文编写前很长一段时间,故配图可能缺失,文章内容基于记忆可能错漏。
此事在三七博客谁之锅?——浅谈Van-nav导致导航页缓存滞留问题亦有记载,可前往查看、互相对照。
前情提要
- 在我的主页创立之时,就一直使用的是目前你进去所能直接看到的那个滚动时钟作为内容,并且其作为该页面的唯一内容存在了很长一段时间。
- 与此同时,由于一些需求,我建立了一个
导航站(该域名目前已弃用)。这种广泛的需求肯定已经有人造好了轮子,果不其然让我找到了一个简洁的导航站:van-nav。配置好之后正常使用了一段时间,功能确实都能如期运行,还不错。
故事开始
- 网站如往常一样继续运行,直到有一天,我的好同志@kamto看到我的导航页觉得不错,于是找到同样的开源项目自行部署了他的导航页。随后过了一段时间,他又“越发越觉得nav的导航样式过于单一”,“于是想自建一个导航页”,并且结合没有太多网站需要经常修改的实际情况,选择并设计了一个静态html页面的导航页。当他完成了他的新导航页后,兴高采烈地过来与我分享,但是当我打开他部署导航页的页面之后,我傻眼了:
问题出现
问题
新的静态页面部署好后,无论如何刷新,都会显示出van-nav的页面,ctrl+f5
刷新可以解决一次问题,但是一旦再按f5刷新,就会再次显示van-nav的页面,但是又因为van-nav的后端已经关闭了,所以会一直获取不到具体内容,显示出只有框架而内容空白的van-nav界面
分析
f12调试可以看到,van-nav的后端确实是关闭了基于此,基本可以判定为某个缓存在生效,并且如果在页面url后增加一个参数(常用的跳过缓存的方法),也确实可以正常响应
所以我开始寻找和缓存相关的内容
结论
啊哈,罪魁祸首果然是吃了service worker的缓存所以导致这样的,这个缓存真厉害啊,优先级居然比
ctrl+f5
还高些。在新页面最后增加一下取消注册service worker的代码,让受影响的用户进行一次强行刷新就好了。
if ("serviceWorker" in navigator) {
navigator.serviceWorker.getRegistrations().then((registrations) => {
registrations.forEach((sw) => sw.unregister());
});
}
self.addEventListener("activate", (e) => {
e.waitUntil(
caches.keys().then((t) => {
return Promise.all(
t.map((n) => {
return caches.delete(n);
})
);
})
);
});
事件回顾
整个事件其实非常简单:van-nav使用了service worker进行缓存,但是由于错误的部署和卸载方法,导致未能正确的在更换页面前取消注册service worker,导致页面一直使用的是本地的内容。以后使用service worker的页面一定要记得在更换内容之前增加更新或者取消缓存的代码,让用户取消本地service worker缓存之后再替换页面,否则就会出现类似问题。
已经受影响的用户可以通过浏览器开发者工具手动清除 Service Worker:
- 打开开发者工具(F12)。
- 进入 Application 标签。
- 在 Service Workers 部分,点击 Unregister。
前文中使用的清除缓存的方法并非最好,建议还是保留注册,通过更新的方式将缓存的内容清掉,否则用户不强行刷新或者手动清除将无法看到最新界面。
很详细,大彬加油!!🥳