为什么 Service Worker 会自动下载新内容,但不更新?



我以这种方式注册服务工作者:

/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready() {
console.log('App is being served from cache by a service worker.');
},
registered() {
console.log('Service worker has been registered.');
},
cached() {
console.log('Content has been cached for offline use.');
},
updatefound() {
console.log('New content is downloading.');
},
updated() {
console.log('New content is available; please refresh.');
},
offline() {
console.log('No internet connection found. App is running in offline mode.');
},
error(error) {
console.error('Error during service worker registration:', error);
}
});
}

当我vue-cli-service build --mode production然后部署到服务器时,在线我可以正确地看到日志:

App is being served from cache by a service worker.
Service worker has been registered.
New content is downloading.
New content is available; please refresh.

它似乎自动下载内容,但从现在起,它仍然总是显示New content is available; please refresh(事实上,内容没有刷新(。它似乎不会自动刷新?只下载?为什么?

如何在updated()上刷新?

在这种情况下,我所做的是解决一个将为用户重新加载页面的承诺。这很好,因为它等待,然后在数据进入后重新加载页面

/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready() {
console.log('App is being served from cache by a service worker.');
},
registered() {
console.log('Service worker has been registered.');
},
cached() {
console.log('Content has been cached for offline use.');
},
updatefound() {
console.log('New content is downloading.');
},
updated() {
console.log('New content is available; please refresh.');
Promise.resolve().then(() => { window.location.reload(true); });
},
offline() {
console.log('No internet connection found. App is running in offline mode.');
},
error(error) {
console.error('Error during service worker registration:', error);
}
});
}

您应该使用服务工作者对象的skipWaiting方法。

也许这可以帮助你:

updated(registration){
const waitingServiceWorker = registration.waiting;
if (waitingServiceWorker) {
waitingServiceWorker.addEventListener('statechange', event => {
if (event.target.state === 'activated') {
window.location.reload();
}
});
waitingServiceWorker.postMessage({ type: 'SKIP_WAITING' });
}
}

此代码是否有效取决于您的service-worker.js内容。

但使用skip waiting的想法是一样的。

最新更新