清单 start_url 未被 Service Worker 缓存
Manifest start_url is not cached by a Service Worker
我正在使用 Lighthouse 来审核我的网络应用程序。我正在努力克服失败,但我仍然坚持这一点:
Failures: Manifest start_url is not cached by a Service Worker.
在我的 manifest.json
我有
"start_url": "index.html",
在我的 worker.js
中,我正在缓存以下内容:
let CACHE_NAME = 'my-site-cache-v1';
let urlsToCache = [
'/',
'/scripts/app.js',
'/index.html'
];
这与我在 Chrome 开发工具的“应用程序”选项卡中看到的一致:
所以...为什么它告诉我 start_url
没有缓存?
这是我的完整 worker.js
文件:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/worker.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
let CACHE_NAME = 'my-site-cache-v1.1';
let urlsToCache = [
'/',
'/scripts/app.js',
'/index.html'
];
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
让我们看看Lighthouse的source code
static assessOfflineStartUrl(artifacts, result) {
const hasOfflineStartUrl = artifacts.StartUrl.statusCode === 200;
if (!hasOfflineStartUrl) {
result.failures.push('Manifest start_url is not cached by a service worker');
}
}
我们可以注意到,它不是检查缓存,而是检查入口点的响应。这样做的原因一定是您的服务人员没有在获取时发送正确的响应。
你会知道它在工作,如果在 DevTools 中,在你的第一个请求中,大小列中会有(来自 ServiceWorker):
您提供的代码有两个问题:
第一个是您将 service worker 代码与 service worker 注册 代码混淆了。 Service Worker注册码应该是你网页上执行的代码。
该代码应包含在您的页面中:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/worker.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
您粘贴的其余内容应该是您的 worker.js 代码。但是 service worker 被安装了,因为你在缓存中有文件,所以我怀疑你只是错误地粘贴了它。
第二个(真正的)问题是 service worker 没有返回这个缓存文件。正如我之前证明的那样,来自 lighthouse 的错误意味着 service worker 没有返回 start_url
入口文件。
最基本的实现代码是:
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request));
});
Service Worker 是事件驱动的,所以当你的页面想要获取一些资源时,Service Worker 会做出反应,并从缓存中提供资源。在现实世界中,你真的不想那样使用它,因为你需要某种后备。我强烈建议阅读第 Serving files from the cache here
部分
编辑:我在 Lighthouse 源代码中创建了 pull request 来澄清错误消息
似乎是 Chrome 灯塔 (chrome v62) 执行通用 fetch()
。请参阅 https://github.com/GoogleChrome/lighthouse/issues/2688#issuecomment-315394447
上的讨论
在我的例子中,offline.html 在“if (event.request.mode === 'navigate'){
”之后提供。
由于使用了 Lighthouse 的通用 fetch()
,Lighthouse 将不会在这个 offline.html 得到服务,并显示 "Manifest start_url is not cached by a Service Worker" 错误。
我通过替换解决了这个问题:
if (event.request.mode === 'navigate'){
和
if (event.request.method === 'GET' ){
我正在使用 Lighthouse 来审核我的网络应用程序。我正在努力克服失败,但我仍然坚持这一点:
Failures: Manifest start_url is not cached by a Service Worker.
在我的 manifest.json
我有
"start_url": "index.html",
在我的 worker.js
中,我正在缓存以下内容:
let CACHE_NAME = 'my-site-cache-v1';
let urlsToCache = [
'/',
'/scripts/app.js',
'/index.html'
];
这与我在 Chrome 开发工具的“应用程序”选项卡中看到的一致:
所以...为什么它告诉我 start_url
没有缓存?
这是我的完整 worker.js
文件:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/worker.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
let CACHE_NAME = 'my-site-cache-v1.1';
let urlsToCache = [
'/',
'/scripts/app.js',
'/index.html'
];
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
让我们看看Lighthouse的source code
static assessOfflineStartUrl(artifacts, result) {
const hasOfflineStartUrl = artifacts.StartUrl.statusCode === 200;
if (!hasOfflineStartUrl) {
result.failures.push('Manifest start_url is not cached by a service worker');
}
}
我们可以注意到,它不是检查缓存,而是检查入口点的响应。这样做的原因一定是您的服务人员没有在获取时发送正确的响应。
你会知道它在工作,如果在 DevTools 中,在你的第一个请求中,大小列中会有(来自 ServiceWorker):
您提供的代码有两个问题:
第一个是您将 service worker 代码与 service worker 注册 代码混淆了。 Service Worker注册码应该是你网页上执行的代码。
该代码应包含在您的页面中:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/worker.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
您粘贴的其余内容应该是您的 worker.js 代码。但是 service worker 被安装了,因为你在缓存中有文件,所以我怀疑你只是错误地粘贴了它。
第二个(真正的)问题是 service worker 没有返回这个缓存文件。正如我之前证明的那样,来自 lighthouse 的错误意味着 service worker 没有返回 start_url
入口文件。
最基本的实现代码是:
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request));
});
Service Worker 是事件驱动的,所以当你的页面想要获取一些资源时,Service Worker 会做出反应,并从缓存中提供资源。在现实世界中,你真的不想那样使用它,因为你需要某种后备。我强烈建议阅读第 Serving files from the cache here
部分编辑:我在 Lighthouse 源代码中创建了 pull request 来澄清错误消息
似乎是 Chrome 灯塔 (chrome v62) 执行通用 fetch()
。请参阅 https://github.com/GoogleChrome/lighthouse/issues/2688#issuecomment-315394447
在我的例子中,offline.html 在“if (event.request.mode === 'navigate'){
”之后提供。
由于使用了 Lighthouse 的通用 fetch()
,Lighthouse 将不会在这个 offline.html 得到服务,并显示 "Manifest start_url is not cached by a Service Worker" 错误。
我通过替换解决了这个问题:
if (event.request.mode === 'navigate'){
和
if (event.request.method === 'GET' ){