我如何在 service worker fetch 中检测到请求是针对清单的 start_url?
How do I detect in a service worker fetch that the request is for the manifest's start_url?
我有一个 PWA,它有一个 manifest.json
with a 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
的值是被请求的相对路由。
我可以在 SW 中加载 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
(解析相对link),appshell
设置为start_url
(看manifest)
显然,所有这些 都可以 进行硬编码。但是,每个 PWA 都需要从 start_url
的缓存中响应,所以这不是一个新问题。在我重新发明轮子之前,有没有更好的方法或者我缺少的东西?
所以...
- 鉴于 service worker 需要 manifest,有没有好的方法可以在 worker 中获取 manifest 的配置?
- 有没有办法解析相对 link 以便与清单进行比较?
我已经想出了如何做到这一点,但它很讨厌,我相信有更好的方法。
特别是我 hard-coding 在清单内联中(我可以 fetch
它,但这也很讨厌)。
const manifest = { start_url: 'appshell' };
然后我用self.location
获取service worker的路径。这包括文件名,所以我 trim 最后:
// 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
而无需缓存其他所有内容,因此这是目前公认的答案。我很想看到一个更好的方法来做到这一点,理想情况下没有困难 coding/fetching manifest.json
这样配置更改就不需要新的服务工作者了。
我有一个 PWA,它有一个 manifest.json
with a 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
的值是被请求的相对路由。
我可以在 SW 中加载 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
(解析相对link),appshell
设置为start_url
(看manifest)
显然,所有这些 都可以 进行硬编码。但是,每个 PWA 都需要从 start_url
的缓存中响应,所以这不是一个新问题。在我重新发明轮子之前,有没有更好的方法或者我缺少的东西?
所以...
- 鉴于 service worker 需要 manifest,有没有好的方法可以在 worker 中获取 manifest 的配置?
- 有没有办法解析相对 link 以便与清单进行比较?
我已经想出了如何做到这一点,但它很讨厌,我相信有更好的方法。
特别是我 hard-coding 在清单内联中(我可以 fetch
它,但这也很讨厌)。
const manifest = { start_url: 'appshell' };
然后我用self.location
获取service worker的路径。这包括文件名,所以我 trim 最后:
// 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
而无需缓存其他所有内容,因此这是目前公认的答案。我很想看到一个更好的方法来做到这一点,理想情况下没有困难 coding/fetching manifest.json
这样配置更改就不需要新的服务工作者了。