如何使 Service Worker 缓存 API 数据并在需要时更新缓存

6

我将我的React应用程序转换为PWA,它部分地运行良好。

我按照这个教程进行操作:https://medium.com/@toricpope/transform-a-react-app-into-a-progressive-web-app-pwa-dea336bd96e6

但是,这篇文章只展示了如何缓存静态数据,而我还需要存储来自服务器的数据。我可以按照这篇帖子的第一个答案的指示执行:How can I cache data from API to Cache Storage in React PWA?,并将存储数据的firebase地址插入到urlsToCache数组中,由应该存储到缓存中的文件填充。

到目前为止,一切都很好,但是在将数据存储到缓存后,即使服务器已更新,应用程序也停止从服务器获取数据,仅使用来自缓存的数据加载页面。这就是我需要解决的问题。

简而言之,我需要从服务器获取数据,将其存储到缓存中以便在离线时使用,并在每次到达服务器时更新缓存。

我正在尝试按照此指南操作,但没有成功:https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#serving-suggestions

这是我的worker.js文件:

var CACHE_NAME = 'pwa-task-manager';
var urlsToCache = [
  '/',
  '/completed',
  '/index.html',
  '/static/js/main.chunk.js',
  '/static/js/0.chunk.js',
  '/static/js/1.chunk.js',
  '/static/js/bundle.js',
  '/calculadora',
  'https://calc-marmo.firebaseio.com/clientes.json',
  'https://calc-marmo.firebaseio.com/adm.json',
];

// Install a service worker
self.addEventListener('install', event => {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

// Cache and return requests
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
        return fetch(event.request);
      }
    )
  );
});

// Update a service worker
self.addEventListener('activate', event => {
  var cacheWhitelist = ['pwa-task-manager'];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

非常感谢您的帮助。

1个回答

7

我继续努力探索,我发现,当我把视角改变为“网络优先”时,在本地主机上它的表现非常出色,但是在真实主机上,我只能获得静态数据,来自 Firebase 的数据没有被缓存,也许问题在于我的配置方式,我不知道。我还尝试了您发布的这个示例,但遇到了同样的问题。作为一种选择,我将静态数据存储在缓存中,并使用 IndexedDB 存储动态数据。如果您有任何想法,可以告诉我为什么会出现这个问题,因为在这种情况下我更愿意使用缓存而不是 IDB,如果没有,无论如何感谢您的时间。 - Berg_Durden
1
Firebase的实时数据库使用websocket与客户端通信。据我所知,在服务工作者中不支持WebSocket。因此,您必须像您所提到的那样将Firebase数据存储在IndexedDB中。(我就是这么做的) - Stef Chäser
你可以分享一段代码片段吗?展示一下你是如何实现的。 - Banny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接