我正在使用Workbox v4.3.1向Web应用程序的用户提供脱机功能。
虽然所有功能都可以在Chrome中完美运行,就像您希望PWA可以正常工作一样(即,所有内容都缓存在本地,但来自应用程序的所有更新都捕获在IndexedDB中,并在应用程序重新联机时同步回服务器)。
但是,对我而言,主要用例是为iOS Safari和PWA提供支持。
虽然所有页面都使用Safari中的Service Worker本地缓存,并且所有脱机更新也都捕获在索引数据库中,如下所示,
但是,当连接返回联机状态时,浏览器(在这种情况下为Safari)不会触发同步事件。尽管Safari本身不支持后台同步,但我希望刷新页面时,如果SW初始化在索引数据库中发现一些要刷新到服务器的数据,则应该手动触发sync事件。
但是这没有发生,我尝试手动监听“消息”-“ replayRequests”,然后重播请求-效果不佳。
这里的任何帮助将不胜感激。这是服务人员代码供参考。
// 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();
}
});
}
答案 0 :(得分:1)
workbox-background-sync
通过在服务工作者进程启动时重播排队的请求,从而在缺少本地支持的浏览器中模拟后台同步功能。 Service Worker进程本应轻巧,寿命短,并且在一段时间内没有任何事件时会被猛烈杀死,然后响应于其他事件而再次启动。
重新加载网页 可能会导致Service Worker进程启动,前提是该进程先前已停止。但是,如果服务工作者仍在运行,则重新加载页面只会导致在现有进程上触发fetch
事件。
服务工作者进程在被杀死之前可以保持空闲的时间间隔取决于浏览器。
Chrome的DevTools提供了一种检查服务人员状态并按需启动/停止状态的方法,但是我不认为Safari的DevTools提供了该功能。如果您想证明服务工作者已停止,然后再次启动,请退出Safari,重新打开它,然后导航回您的Web应用。