我正在使用 workbox v4.3.1 为 Web 应用程序的用户提供离线功能。
虽然在 Chrome 中一切都像您期望的 PWA 一样完美地工作(即一切都缓存在本地,但应用程序的所有更新都被捕获在 IndexedDB 中,并在应用程序重新联机时同步回服务器。
然而,对我而言,主要用例是为 iOS Safari 提供支持并作为 PWA。
虽然所有页面都使用 Safari 中的 Service Worker 在本地缓存,并且所有离线更新也都捕获在索引数据库中,如下所示,
但是,当连接恢复在线时,浏览器(在本例中为 Safari)不会触发同步事件。虽然 Safari 本身不支持后台同步,但我希望当我刷新页面时,如果 SW 初始化发现一些数据要刷新到索引数据库中的服务器,它应该手动触发同步事件。
但这并没有发生,我尝试手动收听“消息” - “replayRequests”,然后重播请求 - 但效果不佳。
如有任何帮助,我们将不胜感激。这是供引用的服务 worker 代码。
// If we're not in the context of a Web Worker, then don't do anything
if ("function" === typeof importScripts) {
importScripts(
"https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"
);
//Plugins
// Background Sync Plugin.
const bgSyncPlugin = new workbox.backgroundSync.Plugin("offlineSyncQueue", {
maxRetentionTime: 24 * 60
});
// Alternate method for creating a queue and managing the events ourselves.
const queue = new workbox.backgroundSync.Queue("offlineSyncQueue");
workbox.routing.registerRoute(
matchCb,
workbox.strategies.networkOnly({
plugins: [
{
fetchDidFail: async ({ request }) => {
await queue.addRequest(request);
}
}
]
}),
"POST"
);
// CacheKeyControlPlugin
const myCacheKeyPlugin = {
cacheKeyWillBeUsed: async ({ request, mode }) => {
normalizedUrl = removeTimeParam(request.url);
return new Request(normalizedUrl);
}
};
if (workbox) {
console.info("SW - Workbox is available and successfully installed");
} else {
console.info("SW - Workbox unavailable");
}
//Intercept all api requests
var matchCb = ({ url, event }) => {
// Filter out the presence api calls
return url.pathname.indexOf("somethingidontwanttocache") == -1;
};
function removeTimeParam(urlString) {
let url = new URL(urlString);
url.searchParams.delete("time");
return url.toString();
}
/* //Pre cache a page and see if it works offline - Temp code
workbox.precaching.precache(getPageAPIRequestURLs(), {
cleanUrls: false
}); */
workbox.routing.registerRoute(
matchCb,
new workbox.strategies.CacheFirst({
cacheName: "application-cache",
plugins: [myCacheKeyPlugin]
})
);
self.addEventListener("message", event => {
if (event.data === "replayRequests") {
queue.replayRequests();
}
});
}
最佳答案
workbox-background-sync
在服务工作进程启动时通过重放排队请求来模拟缺乏 native 支持的浏览器中的后台同步功能。 Service Worker 进程应该是轻量级和短暂的,并且会在一段时间内没有任何事件时被主动终止,然后再次启动以响应更多事件。
重新加载网页可能会导致服务 worker 进程启动,假设它之前已停止。但是,如果 service worker 仍在运行,则重新加载页面只会导致在现有进程上触发 fetch
事件。
service worker 进程在被杀死之前可以保持空闲的时间间隔取决于浏览器。
Chrome 的 DevTools 提供了一种检查服务 worker 状态并按需启动/停止它的方法,但我认为 Safari 的 DevTools 不提供该功能。如果您想保证服务 worker 已停止然后再次启动它,我会退出 Safari,重新打开它,然后导航回您的 Web 应用程序。
关于javascript - Workbox - 后台同步 - 离线发布 - 当浏览器重新在线时重播事件不会被触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57863098/