【发布时间】:2019-04-18 12:57:00
【问题描述】:
我有这个单页应用程序,它带有一个使用令牌(如 example.com/XV252GTH)和各种资产(如 css、favicon 等)构建的动态 URL。
这是我注册 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)
});
但是我如何确定它会及时兑现,即:在软件完成安装后由客户端发送?在这种情况下有什么好的做法?
【问题讨论】:
-
不能用浏览器历史API吗?
标签: javascript progressive-web-apps