我构建了一个门户网站,可以访问多个功能,包括故障单功能。
客户已要求我在线下提供故障单功能。他们希望能够在线时“检出”特定的现有票据,然后在用户的设备超出任何互联网连接范围时可访问(查看/编辑)。此外,他们希望能够在离线时创建新票证。然后,当连接可用时,他们将检入已更改/新创建的票证。
我一直在修改Service Workers并查看一些关于它们的好文档,我觉得我对如何缓存数据有基本的了解。
但是,由于我只想使门户网站的Ticketing部分可以脱机使用,因此我不希望服务工作者在访问门户网站的任何其他页面时缓存或返回缓存数据。所有页面都在同一目录中,因此服务工作程序一旦加载,将默认拦截门户网站中所有页面的所有请求。
如何在Tickets页面打开时将服务工作者设置为仅响应缓存数据?
获取事件时,是否必须手动检查window.location值?例如,
if (window.location == 'https://www.myurl.com/tickets')
{
// try to get the request from network. If successful, cache the result.
// If not successful, try returning the request from the cache.
}
else
{
// only try the network, and don't cache the result.
}
需要为页面加载许多支持文件(即css文件,js文件等),因此仅仅检查页面名称的request.url是不够的。在服务工作者事件中是否可以访问'window.location',这是否是实现此目的的合理方法?
答案 0 :(得分:2)
我知道您提到您目前所有页面都在同一目录中提供...但如果您对Web应用程序的URL结构有任何灵活性,那么最简洁的方法是从URL提供您的票证功能以唯一路径前缀(如/tickets/
)开头,然后从/tickets/service-worker.js
托管您的服务工作者。如果能够利用默认服务工作者范围,并且不必担心服务工作者控制/tickets/
之外的页面,那么重新组织URL的工作可能是值得的。
this answer中有关于确定引用window
客户端URL来自服务工作者的fetch
处理程序的信息。您可以将其与fetch
处理程序中的初始检查结合起来,看看它是否是导航请求并使用它来提前退出。
const TICKETS = '/tickets';
self.addEventListener('fetch', event => {
const requestUrl = new URL(event.request.url);
if (event.request.mode === 'navigate' && requestUrl.pathname !== TICKETS) {
return;
}
const referrerUrl = ...; // See https://stackoverflow.com/questions/50045641
if (referrerUrl.pathname !== TICKETS) {
return;
}
// At this point, you know that it's either a navigation for /tickets,
// or a request for a subresource from /tickets.
});