我有一个页面应用程序,其中包含一个动态URL,该URL由令牌(如example.com/XV252GTH
)和各种资产(如CSS,favicon等)构建。
这是我注册服务工作者的方式:
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的目的。
问题:如何从客户端(注册工作人员的页面)向SW发送请求(/XV252GTH
)?我想我可以在sw.js
self.addEventListener('message', function(event){
updateCache(event.request)
});
但是我如何确定它会及时兑现,即:在软件完成安装后由客户端发送?在这种情况下有什么好的做法?
答案 0 :(得分:3)
如果我理解不对,请纠正我!
您可以在此处预缓存文件:
var cacheAssets = [ 'index.html', 'app.js', 'style.css', 'favicon.ico' ]; function precache() { return caches.open(cacheName).then(function (cache) { return cache.addAll(cacheAssets); }); }
很明显,您缓存了模板,因为您在构建网站之前就缓存了模板,这种方法是正确的,至少不是对所有类型的文件都是如此。
例如,您的favicon.ico
是一个文件,您可能会认为它是static
。另外,它不会经常更改或根本不会更改,并且它不像您的index.html
那样动态。
Source
还应该清楚的是,由于具有更新功能,为什么在重新加载页面后仍具有正确的版本。
此问题的解决方案是您的问题的答案:
如何将客户端(注册工作人员的页面)上的请求(
/XV252GTH
)发送到SW?
如果后端构建了您的网页,则要缓存它,而不是在安装service-worker
之前缓存它。所以这是它的工作方式:
index.html
的缓存。index.html
。取而代之的是,我们向缓存发出请求,并检查index.html
是否在缓存中,至少您是第一次加载该页面。index.html
并将其发送回页面。index.html
后,将其加载到页面并将其存储在缓存中。如果有可用的缓存版本,请使用它,但下次获取更新。
self.addEventListener('fetch', function(event) { event.respondWith( caches.open('mysite-dynamic').then(function(cache) { return cache.match(event.request).then(function(response) { var fetchPromise = fetch(event.request).then(function(networkResponse) { cache.put(event.request, networkResponse.clone()); return networkResponse; }) return response || fetchPromise; }) }) ); });
这些是解决问题的基础。现在,您可以使用相同的方法从各种各样的选项中进行选择,但是还具有一些其他功能。您选择哪一个取决于您,并且在不了解您的详细项目的情况下,没人会告诉您选择哪个。您也不限于一种选择。在某些情况下,您可能将两个或多个选项组合在一起。
Google为您提供的所有选项写了一个很棒的guide,并提供了所有示例的代码示例。他们还解释了您的current version。并非每个选项都会对您有意义且有意义,但我建议您阅读所有内容并仔细阅读。
这是要走的路。
答案 1 :(得分:0)