yPh*_*hil 3 javascript progressive-web-apps
我有这个单页应用程序,带有使用令牌构建的动态 URL,例如example.com/XV252GTHcss、favicon 等各种资产。
以下是我注册 Service Worker 的方法:
navigator.serviceWorker.register('sw.js');
Run Code Online (Sandbox Code Playgroud)
在所述中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());
});
Run Code Online (Sandbox Code Playgroud)
请注意,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));
}());
});
Run Code Online (Sandbox Code Playgroud)
使用此更新功能
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;
});
});
}
Run Code Online (Sandbox Code Playgroud)
在这个阶段,所有资源都在缓存中,但动态生成的页面还没有。只有重新加载后,我才能在缓存中看到另一个条目:/XV252GTH。现在,该应用程序已离线就绪;但页面的重新加载有点违背了整个 Service Worker 的目的。
问题:如何将/XV252GTH客户端(注册worker的页面)的请求( )发送到SW?我想我可以设置一个监听器sw.js
self.addEventListener('message', function(event){
updateCache(event.request)
});
Run Code Online (Sandbox Code Playgroud)
但我如何才能确保它会及时兑现,即:在软件安装完成后由客户端发送?在这种情况下,什么是好的做法?
好的,我从这个页面得到了答案:要缓存在激活时注册工作人员的页面,只需列出所有 SW 的客户端,并获取它们的URL(href属性)。
self.clients.matchAll({includeUncontrolled: true}).then(clients => {
for (const client of clients) {
updateCache(new URL(client.url).href);
}
});
Run Code Online (Sandbox Code Playgroud)