javascript - Service Worker 无法在 Node js 服务器的离线模式下工作

标签 javascript node.js localhost service-worker progressive-web-apps

  • 我正在尝试构建一个采用离线优先策略的PWA
    • 源文件的服务器是 NodeJS 服务器
    • 我目前正在 localhost Node 服务器上对此进行测试(不确定它是否有影响?)。
    • Service worker + 缓存看起来不错,但在离线模式下我只能获得 Chrome 离线页面

让我们进入细节:

服务的页面(通过 http://localhost:8080/place/test url)有一些客户端 JS,我在其中注册了一个 Service Worker:

client.js

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

service-worker.js(基于 Google PWA 教程)

var cacheName = 'myCacheVersion';
var filesToCache = [
    '../',
    '../place/test',
    '../js/client.js',
    '../js/service-worker.js',
    "../css/style.css"
];


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);
    })
  );
});

在 Dev Tools Console 中,一切似乎都很好:

  • 软件已注册
  • 缓存包含我要缓存的元素

但是当我选中离线模式复选框 并刷新我的页面 url 时:http://localhost:8080/place/test , 我只得到 Google Chrome 离线网页

=> 我错过了什么?(它与 nodeJs 有关吗?与本地主机环境有关吗?与我的实现有关吗?)

我已经为这个问题苦苦挣扎了一段时间......

我已经检查了“应用程序”选项卡,我的服务人员显示为已激活并正在运行。

注意:如果在这里发现了类似的问题,但在那里没有令人满意的答案:Service worker not run in offline mode using nodejs server

最佳答案

从根本上说,这与此处回答的问题相同:Service worker is caching files but fetch event is never fired

如果您查看您的控制台,您会发现虽然安装、激活、缓存和注册都发生了,但“获取”不会发生。这是因为您将 service worker 定位在 js 下,因此出于安全原因,Chrome(等)不会将它用于除相同目录或以下目录中的任何 URL。

如果您将 client.jsservice-worker.js 放在同一级别而不是放在 js 子目录中,它将全部开始工作。这将需要更新文件的内容,我将在下面显示这些内容以供引用。

一个小警告:我愚蠢地在 Windows 机器上使用 IIS 来解决这个问题,在它和 Chrome 之间,它们像死神一样紧紧捕获缓存的 HTML 文件和过时的 JS 文件位置。我必须将它们复制到一个子目录中,制作新的 URL,以测试解决方案。

index.html:

<head>
<script src="client.js"></script>
</head>
<body>
<a href="cachetest.html">link to ct</a>
</body>

cachetest.html:

<head>
<script src="client.js"></script>
</head>
<body>cachetest</body>

client.js:

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

serviceworker.js:

var cacheName = 'myCacheVersion';
var filesToCache = [
    '',
    'cachetest.html',
    'client.js',
    'service-worker.js',
//    "css/style.css"
];


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);
    })
  );
});

关于javascript - Service Worker 无法在 Node js 服务器的离线模式下工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45907686/

相关文章:

javascript - colorbox:使用发布数据发送 data-attr

node.js - 差异 websocket.io socket.io

internet-explorer - 127.0.0.1 不适用于 IE 11

apache - 将主机添加到hosts文件

javascript - 如何使用文档的ID从mongoDB集合中删除文档?

javascript - MVC 图像根据文件夹中的数量调整大小

Javascript连续服务器轮询

node.js - MQTT 代理的最大消息长度是多少?

node.js - grunt.js 任务为什么不监听事件?

javascript - 使用 JavaScript 对本地托管 API 中的 JSON 对象进行 http 请求