【问题标题】:Progressive Web App doesn't fetch my cached filesProgressive Web App 不获取我的缓存文件
【发布时间】:2021-10-30 10:02:49
【问题描述】:

我正在尝试将我的天气应用程序变成 PWA,如果用户失去连接,我想创建一个离线页面。 所以我设法将 html 和相关资源(如脚本或 svg)放入浏览器的缓存中,但是当我离线时,只有 html 页面加载,而不是其他内容......

这是缓存中的文件:

这是我离线时在控制台和网络中出现的错误:

如您所见,只有来自 CDN 的 KUTE.js 库(即使显然已加载???)和 CSS 导入的内容(我将 CSS 直接放在我的 html 页面中)已加载。

---如果你想知道“en”文件是什么,那是因为我用Express,Ejs和cookies做了一个翻译系统,所以当你在url中转到/en或/fr时,它会翻译页面无论是英文还是法文。 ---

最后,这是我的 service worker 的代码:

const OFFLINE_VERSION = 1;
const CACHE_NAME = "offline";
const OFFLINE_URL = "offline.html";
const BASE = location.protocol + "//" + location.host;
const CACHED_FILES = [
  "https://cdn.jsdelivr.net/npm/kute.js@2.1.2/dist/kute.min.js",
  `${BASE}/src/favicon/favicon.ico`,
  `${BASE}/src/favicon/android-chrome-192x192.png`,
  `${BASE}/src/favicon/android-chrome-512x512.png`,
  `${BASE}/src/favicon/apple-touch-icon.png`,
  `${BASE}/src/favicon/favicon-16x16.png`,
  `${BASE}/src/favicon/favicon-32x32.png`,
  `${BASE}/src/svg/layered-waves.svg`,
  `${BASE}/js/background.js`,
  `${BASE}/js/animation-blob.js`
];

self.addEventListener('install', (event) => {
  event.waitUntil((async() => {
    const cache = await caches.open(CACHE_NAME);
    await Promise.all(
      [...CACHED_FILES, OFFLINE_URL].map((path) => {
        return cache.add(new Request(path, {cache: "reload"}));
      })
    );
  })());

  self.skipWaiting();
});

self.addEventListener('activate', (event) => {
  event.waitUntil((async () => {
    if ("navigationPreload" in self.registration) {
      await self.registration.navigationPreload.enable();
    }
  })());

  self.clients.claim();
});

self.addEventListener('fetch', (event) => {
  if(event.request.mode === "navigate") {
    event.respondWith((async() => {
      try {
        const preloadResponse = await event.preloadResponse;
        if(preloadResponse) {
          return preloadResponse;
        }

        return await fetch(event.request);
      } catch(e) {
        const cache = await caches.open(CACHE_NAME);
        return await cache.match(OFFLINE_URL);
      }
    })());
  }
});

它是用于创建离线页面的“常规”代码,只是我将多个文件添加到缓存中。

那么您知道为什么我无法获取其他缓存文件吗?

提前谢谢你!

【问题讨论】:

    标签: javascript caching fetch progressive-web-apps browser-cache


    【解决方案1】:

    这个函数作为一个代理来知道它是否应该从缓存或网络中获取数据:

    self.addEventListener('fetch', (event) => {
      if(event.request.mode === "navigate") {
        event.respondWith((async() => {
          try {
            const preloadResponse = await event.preloadResponse;
            if(preloadResponse) {
              return preloadResponse;
            }
    
            return await fetch(event.request);
          } catch(e) {
            const cache = await caches.open(CACHE_NAME);
            return await cache.match(OFFLINE_URL);
          }
        })());
      }
    });
    

    但是这一行 if(event.request.mode === "navigate") 只有在它是一个导航请求时才会产生特殊的行为(当导航器加载一个新页面时)。因此,您需要进行一些小的更改才能使其正常工作,您可以尝试以下方法:

    self.addEventListener('fetch', (event) => {
      event.respondWith((async() => {
        try {
          const preloadResponse = await event.preloadResponse;
          if(preloadResponse) {
            return preloadResponse;
          }
    
          return await fetch(event.request);
        } catch(e) {
          const cache = await caches.open(CACHE_NAME);
          return await cache.match(event.request);
        }
      })());
    });
    

    这通常会使其工作,但现在每个请求都将通过 ServiceWorker 而不仅仅是 navigate 一个

    【讨论】:

    • 谢谢!但这意味着如果我获取的 CDN 不可用,它将加载离线页面?
    • 是的,它会起作用的!如果你在缓存中有存储 url,那就太好了;)(我对我的代码做了一点改动,别忘了升级!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    • 2019-09-07
    • 1970-01-01
    相关资源
    最近更新 更多