我有一个PWA,其中有一个manifest.json
和一个start_url
。
我有一个带有fetch
事件的服务工作者,该事件仅缓存某些请求。
在服务工作者中,这是通过覆盖对缓存中代理的响应(为清楚起见,使用TypeScript)完成的:
self.addEventListener('fetch', (event: FetchEvent) => {
// This MUST be synchronous until respondWith is called
const cache = isCachable(event.request);
if (!isCachable)
return; // Don't proxy, let the network request continue
// Kick off a promise to check the cache, and clone/cache the response otherwise
const proxy: Promise<Response> = cacheResponse(event);
event.respondWith(proxy);
}
我想缓存start_url
,这意味着上面的isCachable
必须能够知道start_url
的值是所请求的相对路由。
我可以在软件中加载manifest.json
,但这确实很笨拙。我可以在SW中对值进行硬编码,但是如果配置更改,则需要更新两个位置。
在fetch
处理程序中,event.request.url
是绝对的,但是start_url
是相对于manifest.json
的-因此,例如,我可能有:
manifest.json
:{ "start_url": "appshell" ... }
www.example.com/folder/
(但可能已部署到sub.example.com
或www.example.com/a/b
或其他任何东西)event.request.url === 'www.example.com/folder/appshell'
触发isCachable
函数来告知应该同步缓存资源。它需要确定www.example.com/folder/appshell
是appshell
(解析相对链接)并且将appshell
设置为start_url
(读取清单)。很显然,所有这些 都可以进行硬编码。但是,每个PWA都需要start_url
的缓存响应,因此这不是一个新问题。在我重新发明轮子之前,有没有更好的方法或缺少的东西?
所以...
答案 0 :(得分:0)
我已经找到了解决方法,但这很讨厌,我敢肯定有更好的方法。
尤其是我正在清单内联中进行硬编码(我可以fetch
,但这也很讨厌)。
const manifest = { start_url: 'appshell' };
然后,我使用self.location
来获取服务人员的路径。这包括文件名,所以我将其修剪掉:
// if file is 'sw.js' that's 5 chars off the end
const applicationRoot = new URL(self.location.href.slice(0, -5) + manifest.start_url);
然后我可以对此进行检查:
self.addEventListener('fetch', (event: FetchEvent) => {
// This MUST be synchronous until respondWith is called
const url = new URL(event.request.url);
if (url.pathname === applicationRoot.pathname) {
// Request is for the start_url, always return something so the PWA starts offline
event.respondWith(...):
}
// ... see question for rest
});
这很笨拙,但是至少它可以始终为缓存的start_url
提供服务而无需缓存其他所有内容,因此,这是目前公认的答案。我希望看到一种更好的方法,理想情况下无需进行硬编码/获取manifest.json
,以便在那里进行配置更改不需要新的服务人员。