由于事件发生在本文编写前很长一段时间,故配图可能缺失,文章内容基于记忆可能错漏。
此事在三七博客谁之锅?——浅谈Van-nav导致导航页缓存滞留问题亦有记载,可前往查看、互相对照。

前情提要

  • 我的主页创立之时,就一直使用的是目前你进去所能直接看到的那个滚动时钟作为内容,并且其作为该页面的唯一内容存在了很长一段时间。
  • 与此同时,由于一些需求,我建立了一个导航站(该域名目前已弃用)。这种广泛的需求肯定已经有人造好了轮子,果不其然让我找到了一个简洁的导航站:van-nav。配置好之后正常使用了一段时间,功能确实都能如期运行,还不错。

故事开始

  • 网站如往常一样继续运行,直到有一天,我的好同志@kamto看到我的导航页觉得不错,于是找到同样的开源项目自行部署了他的导航页。随后过了一段时间,他又“越发越觉得nav的导航样式过于单一”,“于是想自建一个导航页”,并且结合没有太多网站需要经常修改的实际情况,选择并设计了一个静态html页面的导航页。当他完成了他的新导航页后,兴高采烈地过来与我分享,但是当我打开他部署导航页的页面之后,我傻眼了:530FAA4EE2A666E38C4B0F28DFF8BD1E.png

问题出现

问题

新的静态页面部署好后,无论如何刷新,都会显示出van-nav的页面,ctrl+f5刷新可以解决一次问题,但是一旦再按f5刷新,就会再次显示van-nav的页面,但是又因为van-nav的后端已经关闭了,所以会一直获取不到具体内容,显示出只有框架而内容空白的van-nav界面8A167F636610AA4F2A51E49354639FDC.jpg

分析

f12调试可以看到,van-nav的后端确实是关闭了E487E7B46B638AEFA436AB7BD70FE407.png829A0D454FCCA700CBB2C2B1B75A7CCB.png基于此,基本可以判定为某个缓存在生效,并且如果在页面url后增加一个参数(常用的跳过缓存的方法),也确实可以正常响应E66B427EDD1C7E7BC8659DA9AEC9AB33.jpg所以我开始寻找和缓存相关的内容

结论

啊哈,罪魁祸首8B525D4AB1A53B83A25BF64F332034F2.png果然是吃了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:

  1. 打开开发者工具(F12)。
  2. 进入 Application 标签。
  3. 在 Service Workers 部分,点击 Unregister。

前文中使用的清除缓存的方法并非最好,建议还是保留注册,通过更新的方式将缓存的内容清掉,否则用户不强行刷新或者手动清除将无法看到最新界面。