我已经使用MkDocs和Workboxjs创建了一个脱机文档。
我对由MkDocs生成的文件执行workbox generateSW
,该文件会使用precacheAndRoute函数通过预缓存设置生成Service Worker。
这很好,但是当我更新文档并生成新的html文件和Service Worker时,直到完全关闭浏览器,它才提供新内容。刷新或仅关闭选项卡是不够的。
工作程序正在正确地将内容更新到缓存存储中,这可以从Chrome devtools中看到(应用程序->缓存存储-> workbox-precache *),但是无论我点击多少次刷新,浏览器都不会显示新内容。
我使用此功能来注册Service Worker
async function register() {
const registration = await navigator.serviceWorker.register(SW_URL);
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === "installed") {
if (navigator.serviceWorker.controller) {
console.log(
"New content is available; please refresh."
);
} else {
console.log("Content is cached for offline use.");
}
}
};
};
}
我想知道是否需要做一些额外的事情才能使内容正确刷新?
我的workbox-config.js是
module.exports = {
globDirectory: ".doc_build",
globPatterns: ["**/*"],
swDest: ".doc_build/sw.js"
};
在Firefox和Chrome上都会发生这种情况。
答案 0 :(得分:0)
感谢罗伯特·罗恩特里(Robert Rowntree)在我发现的问题注释中的链接。
我的情况是刷新了内容以缓存,但旧版本的precache服务工作程序仍然保持运行状态,其中包含这样的对象列表
{
"url": "index.html",
"revision": "e4919b0cd0e772b3beb2d1f3d09af437"
}
如您所见,它具有旧版本的校验和,它将一直提供该服务,直到停用旧的服务工作者并激活新的服务。
通过查看registration.waiting
可以看到,当旧的服务工作者正在等待停用并安装新的服务工作者时。似乎浏览器“在某个时候”执行了此操作。如果我仅将标签关闭足够长的时间,这似乎确实发生了。
我的问题的解决方案是强制服务人员跳过等待时间。可以通过从更新事件向服务工作者发送消息来做到这一点
async function register() {
const registration = await navigator.serviceWorker.register(SW_URL);
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = async () => {
if (installingWorker.state === "installed") {
if (navigator.serviceWorker.controller) {
console.log(
"New content is available; please refresh."
);
// Send message to the service worker telling
// it should stop waiting for browser to deactivate it
registration.waiting.postMessage("skipWaiting");
} else {
console.log("Content is cached for offline use.");
}
}
};
};
}
然后在Service Worker代码中,我必须处理该消息并调用skipWaiting()
self.addEventListener("message", messageEvent => {
if (messageEvent.data === "skipWaiting") {
return skipWaiting();
}
});
为此,我必须从workbox generateSW
移至workbox injectManifest
才能添加跳过代码。
但是此解决方案中有一些警告。从
开始阅读Robert的链接“最简单,最危险的方法就是跳过安装过程中的等待。”
https://redfin.engineering/how-to-fix-the-refresh-button-when-using-service-workers-a8e27af6df68
幸运的是,这对于我的情况已经足够了。