PWA 踩坑 - 第一次加载页面后无法获取CacheStorage某些资源

第一次加载Service Worker后,脱机再刷新,无法获取CacheStorage某些缓存的资源

对于很多网上的例子,监听fetch,并使用:caches.match获取缓存数据时

self.addEventListener('fetch', function (e) { 
    e.respondWith(
        caches.match(e.request).then(res => {
       ...

在第一次挂载service worker时,我们使用cache.addAll()来将cacheList中指定路径的资源转移到缓存中。

const cacheList = ['./index.html',...]
self.addEventListener('install', e => {
  e.waitUntil(
    caches.open(cacheName)
      .then(cache => {
        return cache.addAll(cacheList);
      })
      .then(() => self.skipWaiting()),
  );
});

问题与步骤

  1. 手动清除Service Worker,及caches缓存。
  2. 第一次加载页面后,马上脱机,然后再刷新。
  3. caches.match(e.request) ,一些特殊的资源会返回undefined,也就是找不到
  4. 控制台查看缓存是有数据的。
  5. 联网状态下,刷新一次后,再脱机,则缓存资源能正常获取。
    这个可以理解,因为这次刷新是在Service Worker生效的条件下。 那么网页中的资源请求都会被Service Worker 的fetch事件拦截,并以e.request 为key添加到cache缓存中。

调查

获取缓存失败的资源的特征:

  • html 页面中<script type="module" >的资源
  • css 中通过@font-face 引入的字体文件(.ttf) (验证了background:url引入的图片没有问题)

因此初步得出结论:

以上形式的资源,不能通过caches.match(Response) 的形式获取——由cache.addAll(cacheList) 缓存的数据

解决方案

caches.match(e.request.url),传入静态资源的url,可正常获取缓存数据。

猜测原因

可能是与这些资源第一次缓存时,存入的CacheStorage的 key不匹配导致的。

因为第一次进入的缓存是通过 cache.addAll 缓存,其缓存到cache的key为何值不清楚,导致二次脱机刷新时获取不到资源。而实际上已经有缓存。

截至写这篇文章时(2022-07-27)时,MDN(CacheStorage)上依旧为实验性。

根据CacheStorage.match(request, options) MDN 文档,其方法有第二个参数,options,它可以一定程度控制match的匹配规则。
从options.ignoreSearch 看出,匹配规则中会判断同一个url的参数是否相同。(这并不是原因)

未实际查明原因。

样本较少,若有错误或补充,敬请指出更正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值