使用图像和CSS脱机回退页面



我正在尝试将我的网站设置为在没有互联网连接的情况下加载时具有回退页面。为此,我在web.dev上遵循以下指南:";创建脱机回退页面";

我修改了文章中的示例ServiceWorker以符合我的目的,包括能够在回退脱机页面中提供外部CSS和图像:

// Incrementing OFFLINE_VERSION will kick off the install event and force
// previously cached resources to be updated from the network.
const OFFLINE_VERSION = 1;
const CACHE_NAME = "offline";
// Customize this with a different URL if needed.
const OFFLINE_URL = "offline.html";
self.addEventListener("install", (event) => {
event.waitUntil(
(async () => {
const cache = await caches.open(CACHE_NAME);
// Setting {cache: 'reload'} in the new request will ensure that the response
// isn't fulfilled from the HTTP cache; i.e., it will be from the network.
await cache.add(new Request(OFFLINE_URL, { cache: "reload" }));
await cache.add(new Request("offline.css", { cache: "reload" }));
await cache.add(new Request("logo.png", { cache: "reload" }));
await cache.add(new Request("unsupportedCloud.svg", { cache: "reload" }));
})()
);
});
self.addEventListener("activate", (event) => {
// Tell the active service worker to take control of the page immediately.
self.clients.claim();
});
self.addEventListener("fetch", (event) => {
// We only want to call event.respondWith() if this is a navigation request
// for an HTML page.
if (event.request.mode === "navigate") {
if (event.request.url.match(/SignOut/)) {
return false;
}
event.respondWith(
(async () => {
try {
const networkResponse = await fetch(event.request);
return networkResponse;
} catch (error) {
// catch is only triggered if an exception is thrown, which is likely
// due to a network error.
// If fetch() returns a valid HTTP response with a response code in
// the 4xx or 5xx range, the catch() will NOT be called.
console.log("Fetch failed; returning offline page instead.", error);
const cache = await caches.open(CACHE_NAME);
const cachedResponse = await cache.match(OFFLINE_URL);
return cachedResponse;
}
})()
);
}
});

然而,当offline.html页面加载时,它无法加载图像和CSS;图像加载失败,出现404错误,对CSS的请求甚至没有显示在浏览器开发控制台的"网络"选项卡中。

我希望从ServiceWorker缓存中提取图像和CSS,但似乎两者都不是

我是否遗漏了ServiceWorkers缓存请求的方式或获取请求的方式?或者关于如何设计脱机回退页面以工作?

事实证明,找不到资产有几个原因。

第一个原因是因为当它们被保存到缓存时,它们与存储在Service Worker文件旁边的整个路径一起保存。

因此,保存的路径与static/PWA/[offline.css, logo.png, unsupportedCloud.svg]类似,但请求它们的页面的路径在根目录中。在offline.html中,我不得不这样引用它们:<img src="static/PWA/unsupportedCloud.svg" class="unsupported-cloud" />

第二个原因是Service Worker仅检查导航类型的fetch事件。在我的示例中,您可以看到我已经编写了if (event.request.mode === "navigate") {...},所以我们只尝试使用我们在导航事件中设置的缓存,这不会捕获fetch事件来获取资产。为了解决这个问题,我为no-cors事件模式设置了一个新的检查:else if (event.request.mode === "no-cors") {...}

这两个修复程序使我能够从Service Worker安装时设置的脱机缓存中获取资产。通过其他一些小的修复,这解决了我的问题!

最新更新