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


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

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

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

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

    1. const cacheList = ['./index.html',...]
    2. self.addEventListener('install', e => {
    3. e.waitUntil(
    4. caches.open(cacheName)
    5. .then(cache => {
    6. return cache.addAll(cacheList);
    7. })
    8. .then(() => self.skipWaiting()),
    9. );
    10. });

    问题与步骤

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

    调查

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

    • html 页面中 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的参数是否相同。(这并不是原因)

    未实际查明原因。

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

  • 相关阅读:
    设计模式-策略设计模式(一般通过工厂方法模式来实现策略类的声明)
    OWT Server信令分析 (下) [Open WebRTC Toolkit]
    使用requests库下载文件的技术解析
    C++设计模式之装饰者模式(结构型模式)
    史上最全的Java进阶书籍推荐
    OpenCV图像处理学习十八,霍夫变换实现交通车道线检测
    什么是软件工程?
    Go语言学习笔记——日期时间处理库Carbon
    Python:最低要求
    从C语言基础到高级C语言 (结构体和位域)
  • 原文地址:https://blog.csdn.net/qq_35459724/article/details/126023722