【发布时间】:2020-12-21 19:18:15
【问题描述】:
我正在使用 NextJS 和 Workbox 来创建 PWA 和我需要的这个库的离线支持:https://github.com/shadowwalker/next-pwa。在上面的 repo 中有一个我需要的示例:离线后备。我不需要应用程序在离线模式下完全运行,只需要一个指示连接丢失的后备页面。
我阅读了关于综合后备的工作箱部分:https://developers.google.com/web/tools/workbox/guides/advanced-recipes#comprehensive_fallbacks
当任何其他路由无法生成响应时会触发一个 catchHandler,但问题是我在捕获 XMLHttpRequests (XHR) 错误时遇到了很大的麻烦。
例如,当客户端将请求发送到 API 时,如果没有互联网连接,我想呈现一个备用页面。如果失败的请求是“文档”,则处理程序仅处理后备页面,并且由于 XHR 请求不是文档,我无法处理它们。
import { clientsClaim } from 'workbox-core';
import { ExpirationPlugin } from 'workbox-expiration';
import {
NetworkOnly,
NetworkFirst,
StaleWhileRevalidate,
} from 'workbox-strategies';
import {
registerRoute,
setDefaultHandler,
setCatchHandler,
} from 'workbox-routing';
import {
precacheAndRoute,
cleanupOutdatedCaches,
matchPrecache,
} from 'workbox-precaching';
clientsClaim();
// must include following lines when using inject manifest module from workbox
// https://developers.google.com/web/tools/workbox/guides/precache-files/workbox-build#add_an_injection_point
const WB_MANIFEST = self.__WB_MANIFEST;
// Precache fallback route and image
WB_MANIFEST.push({
url: '/fallback',
revision: '1234567890',
});
cleanupOutdatedCaches();
precacheAndRoute(WB_MANIFEST);
registerRoute(
'/',
new NetworkFirst({
cacheName: 'start-url',
plugins: [
new ExpirationPlugin({
maxEntries: 1,
maxAgeSeconds: 86400,
purgeOnQuotaError: !0,
}),
],
}),
'GET'
);
// disable image cache, so we could observe the placeholder image when offline
registerRoute(
/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
new NetworkOnly({
cacheName: 'static-image-assets',
plugins: [
new ExpirationPlugin({
maxEntries: 64,
maxAgeSeconds: 86400,
purgeOnQuotaError: !0,
}),
],
}),
'GET'
);
registerRoute(
/\.(?:js)$/i,
new StaleWhileRevalidate({
cacheName: 'static-js-assets',
plugins: [
new ExpirationPlugin({
maxEntries: 32,
maxAgeSeconds: 86400,
purgeOnQuotaError: !0,
}),
],
}),
'GET'
);
registerRoute(
/\.(?:css|less)$/i,
new StaleWhileRevalidate({
cacheName: 'static-style-assets',
plugins: [
new ExpirationPlugin({
maxEntries: 32,
maxAgeSeconds: 86400,
purgeOnQuotaError: !0,
}),
],
}),
'GET'
);
registerRoute(
/\.(?:json|xml|csv)$/i,
new NetworkFirst({
cacheName: 'static-data-assets',
plugins: [
new ExpirationPlugin({
maxEntries: 32,
maxAgeSeconds: 86400,
purgeOnQuotaError: !0,
}),
],
}),
'GET'
);
registerRoute(
/https:\/\/api[a-z-]*\.pling\.net\.br.*$/i,
new NetworkFirst({
cacheName: 'pling-api',
networkTimeoutSeconds: 10,
plugins: [
new ExpirationPlugin({
maxEntries: 16,
maxAgeSeconds: 86400,
purgeOnQuotaError: !0,
}),
],
}),
'GET'
);
registerRoute(
/https:\/\/[a-zA-Z0-9]+\.cloudfront.net\/.*$/i,
new NetworkFirst({
cacheName: 'cloudfront-assets',
networkTimeoutSeconds: 10,
plugins: [
new ExpirationPlugin({
maxEntries: 32,
maxAgeSeconds: 86400,
purgeOnQuotaError: !0,
}),
],
}),
'GET'
);
registerRoute(
/.*/i,
new NetworkFirst({
cacheName: 'others',
networkTimeoutSeconds: 10,
plugins: [
new ExpirationPlugin({
maxEntries: 32,
maxAgeSeconds: 86400,
purgeOnQuotaError: !0,
}),
],
}),
'GET'
);
setDefaultHandler(new NetworkOnly());
// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(({ event }) => {
switch (event.request.destination) {
case 'document':
// If using precached URLs:
return matchPrecache('/fallback');
case 'image':
return matchPrecache('/static/images/fallback.png');
default:
// If we don't have a fallback, just return an error response.
// Switch statement for XHR Requests
return Response.error();
}
});
【问题讨论】:
标签: next.js progressive-web-apps workbox