我在基于工作簿的服务工作者中为NavigationRoute使用NetworkFirst策略,以便在用户脱机时为导航请求提供缓存响应。
workbox.routing.registerRoute(
new workbox.routing.NavigationRoute(
new workbox.strategies.NetworkFirst({
cacheName: 'static-pages',
}),
),
);
当我导航到一个页面时,导航请求会被缓存,然后我可以在脱机时再次访问它。到目前为止还不错。
但是,我需要预先缓存PWA启动URL,因此,如果用户从任何页面安装PWA,脱机并尝试打开它,则PWA启动的URL将被缓存并可用。事实上,从Chrome 91开始,这将是可安装性提示的要求。
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.open('static-pages').then(cache => {
const startUrl = 'https://my-pwa-start-url...';
return cache.add(startUrl);
})
);
});
这里的问题是,startUrl
的请求不是navigation
请求,因此即使它被缓存在static-pages
缓存中,在导航到起始URL时也不会使用它。
我尝试手动构建导航请求,例如
const startUrlRequest = new Request(startUrl, { mode: 'navigate' });
return cache.add(startUrlRequest);
但后来我得到了这个错误:
TypeError: Failed to construct 'Request': Cannot construct a Request with a RequestInit whose mode member is set as 'navigate'.
有没有任何方法可以在不实际导航到页面的情况下预缓存NavigationRequest?
您正在尝试的基本方法——调用cache.add(startUrl)
——应该很好,尽管我建议您在install
处理程序中这样做,而不是在activate
中。
一般来说,不需要手动构建导航请求并将其传递给cache.add()
,正如您所发现的,实际上无法在不引发异常的情况下构建导航请求。
唯一的东西";特别的";关于导航请求和缓存的响应,重定向的响应不能用来满足导航请求,所以只需确保缓存的URL不会导致30倍的重定向。
因此,我的猜测是,您的缓存已被正确预填充,但NetworkFirst
策略中存在缓存未命中。一种可能的解释是,您显式缓存的URL中存在查询参数,而导航过程中请求的URL中这些参数不匹配。您应该能够通过使用Chrome的DevTools检查缓存和网络流量来确认这一点。如果这确实是问题所在,您可以告诉Workbox在尝试通过传递ignoreSearch
匹配选项来查找匹配的缓存条目时忽略查询参数:
new workbox.strategies.NetworkFirst({
cacheName: 'static-pages',
matchOptions: {
ignoreSearch: true,
},
})