服务人员无法离线获取资产

时间:2019-07-17 09:59:04

标签: node.js angular service-worker offline offline-caching

我正试图使我的网站脱机工作,但似乎无法正常工作。 我的项目基于node.js以及由angular生成的外部js文件。

这一切似乎都工作正常,当服务器正在运行并且我进入localhost:3000时,service worker安装正确,那么如果我进入Chrome Devtools中的“应用程序”选项卡,然后选中“脱机”,我重新加载页面,它也可以工作。

但是,如果我关闭服务器并重新加载页面,则会在控制台中收到以下错误:An unknown error occurred when fetching the script.

这是我的index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>{{ title }}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel='stylesheet' href='/stylesheets/style.css' />
    <link rel="icon" type="image/x-icon" href="/dist/favicon.ico">
    <link href="/dist/assets/fontawesome.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,500&display=swap" rel="stylesheet">
  </head>
  <body>
    {% block body %}{% endblock %}
  </body>
  <script src="/client.js"></script>
  <script src="/service-worker.js"></script>
  <script src="/dist/runtime-es2015.js" type="module"></script>
  <script src="/dist/polyfills-es2015.js" type="module"></script>
  <script src="/dist/runtime-es5.js" nomodule></script>
  <script src="/dist/polyfills-es5.js" nomodule></script>
  <script src="/dist/styles-es2015.js" type="module"></script>
  <script src="/dist/styles-es5.js" nomodule></script>
  <script src="/dist/vendor-es2015.js" type="module"></script>
  <script src="/dist/main-es2015.js" type="module"></script>
  <script src="/dist/vendor-es5.js" nomodule></script>
  <script src="/dist/main-es5.js" nomodule></script>
  </body>
</html>

client.js:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker
             .register('./service-worker.js')
             .then(function() { console.log('Service Worker Registered'); });
}

service-worker.js:

var cacheName = 'myCacheVersion';
var filesToCache = [
    '/dist/favicon.ico',
    '/dist/runtime-es2015.js',
    '/dist/polyfills-es2015.js',
    '/dist/runtime-es5.js',
    '/dist/polyfills-es5.js',
    '/dist/styles-es2015.js',
    '/dist/styles-es5.js',
    '/dist/vendor-es2015.js',
    '/dist/main-es2015.js',
    '/dist/vendor-es5.js',
    '/dist/main-es5.js',
    '/client.js',
    '/service-worker.js',
];


self.addEventListener('install', function(e) {
  console.log('[ServiceWorker] Install');
  e.waitUntil(
    caches.open(cacheName).then(function(cache) {
      console.log('[ServiceWorker] Caching app shell');
      return cache.addAll(filesToCache);
    })
  );
});

self.addEventListener('activate', function(e) {
  console.log('[ServiceWorker] Activate');
  e.waitUntil(
    caches.keys().then(function(keyList) {
      return Promise.all(keyList.map(function(key) {
        if (key !== cacheName) {
          console.log('[ServiceWorker] Removing old cache', key);
          return caches.delete(key);
        }
      }));
    })
  );
  return self.clients.claim();
});

self.addEventListener('fetch', function(e) {
  console.log('[ServiceWorker] Fetch', e.request.url);
  e.respondWith(
    caches.match(e.request).then(function(response) {
      return response || fetch(e.request);
    })
  );
});

对为什么它不起作用有任何想法吗?

这是我处于假脱机模式时控制台中的内容: enter image description here

这就是我真正离线时的状态 enter image description here

1 个答案:

答案 0 :(得分:0)

首先:永远不要缓存service-worker.js!从文件中删除它以进行缓存。浏览器具有可用的本地副本,只要浏览器从服务器更新脚本,就会使用该副本。永远不要有理由将脚本放入由SW管理的缓存中。 <script src="/service-worker.js"></script>这也是您不应该执行的操作。不应通过常规脚本标签包括service-worker.js,而应像在其他文件中那样通过navigator.serviceWorker.register(...)调用来包括它:)

您收到错误消息,因为浏览器通过Service Worker尝试加载服务器的根目录,并且该根目录不可用。加载会导致一个不可用的错误,并且在yuor Service Worker的缓存中也找不到该错误,因为您没有对其进行缓存(未在要缓存的文件中列出)。

我真的很想知道您提供的这段代码实际上根本不能脱机工作,因为它没有缓存根页。它根本不应该脱机工作-Service Worker不会缓存根,因此离线时应该无法从缓存中获取任何内容。

毫无价值的浏览器没有连接(脱机)和网站不可用(服务器关闭)是两种完全不同的情况。在前者中,SW知道网络不可用,因此在决定如何响应时(如果被告知),可以将其考虑在内。但是,在后者中,浏览器正试图从网络中获取某些信息,而网络本身仍在工作,但目的地本身不可用。这是连接到站点的故障,不是脱机模式。在后一种情况下,SW必须决定如何处理,也许必须回退到offline.html占位符页面,并且最显着的是不缓存响应。