Service Worker 无法在节点 js 服务器的离线模式下工作
Service Worker not working in Offline mode with node js server
- 我正在尝试使用离线优先策略构建 PWA。
- 源文件的服务器是 NodeJS 服务器。
- 我目前正在 localhost 节点服务器上测试它(不确定它有影响吗?)。
- 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 控制台中,一切似乎都很好:
- 软件已注册
- 缓存中包含我要缓存的元素
但是当我选中 离线模式复选框 并刷新我的页面 url : http://localhost:8080/place/test 时,我只得到 Google Chrome 离线网页.
=> 我在那里遗漏了什么?(它与 nodeJs 有关吗?与本地主机环境有关吗?与我的实现有关吗?)
我已经为此苦苦挣扎了一段时间...
我已经检查了 "Application" 选项卡,我的服务人员显示为已激活并且 运行。
注意:如果在这里发现了类似的问题,但在那里没有令人满意的答案:Service worker not run in offline mode using nodejs server
基本上这与此处回答的问题相同:
如果您查看控制台,您会发现虽然安装、激活、缓存和注册都在进行,但 "fetch" 不会。这是因为您将 service worker 定位在 js
下,因此出于安全原因 Chrome(等)不会将它用于除相同目录或以下目录中的任何 URL。
如果您将 client.js
和 service-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);
})
);
});
- 我正在尝试使用离线优先策略构建 PWA。
- 源文件的服务器是 NodeJS 服务器。
- 我目前正在 localhost 节点服务器上测试它(不确定它有影响吗?)。
- 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 控制台中,一切似乎都很好:
- 软件已注册
- 缓存中包含我要缓存的元素
但是当我选中 离线模式复选框 并刷新我的页面 url : http://localhost:8080/place/test 时,我只得到 Google Chrome 离线网页.
=> 我在那里遗漏了什么?(它与 nodeJs 有关吗?与本地主机环境有关吗?与我的实现有关吗?)
我已经为此苦苦挣扎了一段时间...
我已经检查了 "Application" 选项卡,我的服务人员显示为已激活并且 运行。
注意:如果在这里发现了类似的问题,但在那里没有令人满意的答案:Service worker not run in offline mode using nodejs server
基本上这与此处回答的问题相同:
如果您查看控制台,您会发现虽然安装、激活、缓存和注册都在进行,但 "fetch" 不会。这是因为您将 service worker 定位在 js
下,因此出于安全原因 Chrome(等)不会将它用于除相同目录或以下目录中的任何 URL。
如果您将 client.js
和 service-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);
})
);
});