问题描述
在使用WorkBox(5.1.3)并设置service-worker.js时
precacheAndRoute([
{url: '/version.txt',revision: 'v1' },]);
我可以在浏览器中导航到localhost://version.txt
,并在chrome控制台中看到该内容是通过从工作箱缓存来获取的。
控制台中的消息显示:
workBox Precaching is responding to: /version.txt
但是当尝试通过以下方式在我的javascript应用程序中获取资源时:
window
.fetch('/version.txt')
.then((response) => {
if (response.status >= 200 && response.status < 300) {
return response.text();
} else {
throw Error('no version');
}
})
.then((data) => {
console.log('content: ' + data);
})
.catch((error) => {
console.log(error);
});
}
fetch命令将尝试直接从网络中读取此内容,并跳过工作箱预缓存。另外,在离线模拟时,我在获取错误而不是缓存的响应时遇到错误。
发疯;-)
解决方法
您希望服务人员拦截您的导航请求并提供文件。
您应该使用工作箱中的预缓存机制
例如
new routing.registerRoute(new routing.NavigationRoute(
new precaching.createHandlerBoundToURL('/version.txt'),{
allowlist: [new RegExp('/version.txt')]
}
))
,
深入研究此问题后-我至少在我的网站上发现了问题
完整的示例:
/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My New Project!</title>
</head>
<body>
<h1>Example Service Worker</h1>
<p>A simple Test</>
<!-- Scripts -->
<script src="index.js"></script>
</body>
</html>
/index.js
let registration;
var initServiceWorker = () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('./sw.js')
.then((reg) => registration = reg)
.catch((error) => console.log('Registration failed with ' + error));
}
}
var fetchTest = () => {
console.log('VERSION FETCH Test looking for: /version.txt');
window
.fetch('/version.txt',{ method: 'GET'})
.then((response) => {
if (response.status >= 200 && response.status < 300) {
return response.text();
} else {
throw Error('no version.txt file');
}
})
.then((data) => {
console.log('AVILABLE VERSION FETCH: ' + String(data).trim());
})
.catch((error) => {
console.log(error);
});
}
var xmlhttpTest = () => {
console.log('VERSION XHR Test looking for: /version.txt');
var xhr = new XMLHttpRequest();
xhr.open("GET",'/version.txt',true);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log('AVILABLE VERSION XHR: ' + xhr.responseText);
}
}
}
// initialize request
xhr.send(null);
}
console.log("JavaScript is amazing!");
initServiceWorker();
setTimeout(() => fetchTest(),5000);
setTimeout(() => xmlhttpTest(),10000);
setTimeout(() => { console.log('Registration update ...'); registration.update()},20000);
setTimeout(() => fetchTest(),30000);
setTimeout(() => xmlhttpTest(),35000);
/sw.js
// Sample service worker
const SW_VERSION = 'a2';
self.addEventListener('install',(event) => {
console.log('SW INSTALL: ' + SW_VERSION);
skipWaiting();
});
self.addEventListener('activate',(event) => {
console.log('SW ACTIVATE: ' + SW_VERSION);
skipWaiting();
});
self.addEventListener("fetch",function(event) {
console.log('WORKER (' + SW_VERSION + '): fetch event in progress ... ' + event.request.url);
if (event.request.method !== 'GET') {
console.log('WORKER: fetch event ignored.',event.request.method,event.request.url);
return;
}
});
/version.txt
v1.0.0
您可能需要查看控制台,才能发现在使用FETCH或XMLHTTREQUEST时,来自Service Worker的访存事件也会删除一条消息。
现在关于(我的)问题:
如果将具有fetch和xmlHttprequest的javascript(/index.js)与服务工作者(/sw.js)放在同一位置(范围)一切正常,
但是
如果将javascript保留在(/js/index.js)这样的子文件夹中,则这不会引起服务工作者(/sw.js)的关注, 任何其他事情即使/ js应该在范围之内?
很奇怪,但现在很高兴得到它;-)