我有一个单页应用程序,带有使用 token 构建的动态 URL,例如 example.com/XV252GTH
以及各种资源,如 css、favicon 等。
以下是我注册 Service Worker 的方法:
navigator.serviceWorker.register('sw.js');
并在说sw.js
,我在安装时预先缓存了资源:
var cacheName = 'v1';
var cacheAssets = [
'index.html',
'app.js',
'style.css',
'favicon.ico'
];
function precache() {
return caches.open(cacheName).then(function (cache) {
return cache.addAll(cacheAssets);
});
}
self.addEventListener('install', function(event) {
event.waitUntil(precache());
});
请注意 index.html
(注册 Service Worker)页面只是一个模板,在发送到客户端之前会在服务器上填充;所以在这个预缓存阶段,我只缓存模板,而不缓存页面。
现在,在 fetch 事件中,任何不在缓存中的请求资源都会被复制到其中:
addEventListener('fetch', event => {
event.respondWith(async function() {
const cachedResponse = await caches.match(event.request);
if (cachedResponse) return cachedResponse;
return fetch(event.request).then(updateCache(event.request));
}());
});
使用此更新功能
function updateCache(request) {
return caches.open(cacheName).then(cache => {
return fetch(request).then(response => {
const resClone = response.clone();
if (response.status < 400)
return cache.put(request, resClone);
return response;
});
});
}
在此阶段,所有资源都在缓存中,但动态生成的页面除外。只有重新加载后,我才能在缓存中看到另一个条目:/XV252GTH
。 现在,该应用程序已离线就绪;但是页面的重新加载有点违背了整个 Service Worker 的目的。
问题:如何从客户端(注册worker的页面)向SW发送请求( /XV252GTH
)?我想我可以在sw.js
中设置一个监听器
self.addEventListener('message', function(event){
updateCache(event.request)
});
但是我如何才能确保它会及时兑现,即:在软件安装完成后由客户端发送?在这种情况下,什么是好的做法?
最佳答案
好的,我从 this page 得到了答案:要缓存在激活时注册工作程序的页面,只需列出所有软件的客户端,并获取它们的 URL (href
属性)。
self.clients.matchAll({includeUncontrolled: true}).then(clients => {
for (const client of clients) {
updateCache(new URL(client.url).href);
}
});
关于javascript - 服务人员 : How to cache the first (dynamic) page,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55746555/