如何每 30 分钟更新一次 Service Worker 中的缓存文件?
How to update the cached files in my service worker every 30 minutes?
我有这个服务人员:
//IMPORT POLYFILL
importScripts('cache-polyfill.js');
//INSTALL
self.addEventListener('install', function(e) {
e.waitUntil(
caches.open('stock_item_balance_v1').then(function(cache) {
return cache.addAll([
'/app/offline_content/purchase/stock_items/stock_items_balance.php',
'/app/offline_content/purchase/stock_items/js/stock_items_balance.js'
]);
})
);
});
//FETCH (FETCH IS WHEN YOU CHECK FOR INTERNET)
self.addEventListener('fetch', function(event) {
//console.log(event.request.url);
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
});
在“stock_items_balance.php”中,我从我的数据库中获取数据。所以每 30 分钟我想更新我的缓存页面并重新加载 window.
所以首先我有一个检查互联网连接的脚本。
如果为真,我想 clean/update 缓存并重新加载页面。
我该怎么做?
//INTERVAL
setInterval(function(){
//CLEAN/UPDATE CACHED FILES
serviceworker.update(); // ???
//RELOAD PAGE
window.location.reload();
}, 180000);
(我认为您有一个更大的问题,即您所描述的方法是否真的会为您的用户提供良好的、可预测的、支持离线的体验,但我只想专注于您提出的实际技术问题。)
向 service worker 发送消息
首先,您应该记住,可以为同一个 URL 打开多个选项卡,如果您这样做,您最终可能会得到更新代码 运行 多次。在异步缓存更新完成后,此答案中的代码通过获取服务工作者的所有活动客户端的列表并告诉每个客户端导航到当前 URL(实际上是重新加载)。
// Additions to your service worker code:
self.addEventListener('message', (event) => {
// Optional: if you need to potentially send different
// messages, use a different identifier for each.
if (event.data === 'update') {
event.waitUntil((async () => {
// TODO: Move these URLs and cache names into constants.
const cache = await caches.open('stock_item_balance_v1');
await cache.addAll([
'/app/offline_content/purchase/stock_items/stock_items_balance.php',
'/app/offline_content/purchase/stock_items/js/stock_items_balance.js'
]);
const windowClients = await clients.matchAll();
for (const windowClient of windowClients) {
// Optional: check windowClient.url first and
// only call navigate() if it's the URL for one
// specific page.
windowClient.navigate(windowClient.url);
}
})());
}
});
// Additions to your window/page code:
setInterval(() => {
if (navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage('update');
}
}, 180000);
什么行不通
缓存存储 API 可从服务工作者内部和页面的 window
范围内使用。通常我建议人们做的是从 window
上下文打开相同的缓存,然后调用 cache.add()
以使用来自网络的最新缓存条目更新缓存条目。但是,从 window
上下文 调用 cache.add()
将 导致网络请求被您的 fetch
处理程序拦截,此时,您的响应实际上不会来自网络。通过从服务工作者内部调用 cache.add()
,您可以 guarantee 生成的网络请求不会触发您的 fetch
处理程序。
我有这个服务人员:
//IMPORT POLYFILL
importScripts('cache-polyfill.js');
//INSTALL
self.addEventListener('install', function(e) {
e.waitUntil(
caches.open('stock_item_balance_v1').then(function(cache) {
return cache.addAll([
'/app/offline_content/purchase/stock_items/stock_items_balance.php',
'/app/offline_content/purchase/stock_items/js/stock_items_balance.js'
]);
})
);
});
//FETCH (FETCH IS WHEN YOU CHECK FOR INTERNET)
self.addEventListener('fetch', function(event) {
//console.log(event.request.url);
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
});
在“stock_items_balance.php”中,我从我的数据库中获取数据。所以每 30 分钟我想更新我的缓存页面并重新加载 window.
所以首先我有一个检查互联网连接的脚本。
如果为真,我想 clean/update 缓存并重新加载页面。
我该怎么做?
//INTERVAL
setInterval(function(){
//CLEAN/UPDATE CACHED FILES
serviceworker.update(); // ???
//RELOAD PAGE
window.location.reload();
}, 180000);
(我认为您有一个更大的问题,即您所描述的方法是否真的会为您的用户提供良好的、可预测的、支持离线的体验,但我只想专注于您提出的实际技术问题。)
向 service worker 发送消息
首先,您应该记住,可以为同一个 URL 打开多个选项卡,如果您这样做,您最终可能会得到更新代码 运行 多次。在异步缓存更新完成后,此答案中的代码通过获取服务工作者的所有活动客户端的列表并告诉每个客户端导航到当前 URL(实际上是重新加载)。
// Additions to your service worker code:
self.addEventListener('message', (event) => {
// Optional: if you need to potentially send different
// messages, use a different identifier for each.
if (event.data === 'update') {
event.waitUntil((async () => {
// TODO: Move these URLs and cache names into constants.
const cache = await caches.open('stock_item_balance_v1');
await cache.addAll([
'/app/offline_content/purchase/stock_items/stock_items_balance.php',
'/app/offline_content/purchase/stock_items/js/stock_items_balance.js'
]);
const windowClients = await clients.matchAll();
for (const windowClient of windowClients) {
// Optional: check windowClient.url first and
// only call navigate() if it's the URL for one
// specific page.
windowClient.navigate(windowClient.url);
}
})());
}
});
// Additions to your window/page code:
setInterval(() => {
if (navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage('update');
}
}, 180000);
什么行不通
缓存存储 API 可从服务工作者内部和页面的 window
范围内使用。通常我建议人们做的是从 window
上下文打开相同的缓存,然后调用 cache.add()
以使用来自网络的最新缓存条目更新缓存条目。但是,从 window
上下文 调用 cache.add()
将 导致网络请求被您的 fetch
处理程序拦截,此时,您的响应实际上不会来自网络。通过从服务工作者内部调用 cache.add()
,您可以 guarantee 生成的网络请求不会触发您的 fetch
处理程序。