Как я могу определить, имеет ли браузер пользователя поддержку Background Syn c из внутри сервисного работника ?
Я знаю, как это обнаружить на стороне приложения, но не из самого сервисного работника.
В основном я использую фоновую синхронизацию Workbox c, и все это прекрасно работает в Chrome и Chrome Mobile.
Я знаю, что в Workbox есть Background Syn c «откат» для браузеров, которые не поддерживают Background Syn c, но это не очень хорошо работает, поэтому я бы предпочел просто отключить Background Syn c полностью для браузеров, которые его не поддерживают.
Вот мой рабочий файл для справки. Вы можете видеть, что есть 3 блока кода, которые я не хочу выполнить, если браузер не поддерживает фоновую синхронизацию c (я пометил их *** I ONLY WANT TO RUN THIS CODE IF BACKGROUND SYNC IS SUPPORTED ***
):
/*
* This file (which will be your service worker)
* is picked up by the build system ONLY if
* quasar.conf > pwa > workboxPluginMode is set to "InjectManifest"
*/
/*
config
*/
workbox.setConfig({ debug: false }) // disable workbox console logs
workbox.precaching.precacheAndRoute(self.__precacheManifest || [])
/*
basic routes
*/
workbox.routing.registerRoute(
/^https:\/\/firestore.googleapis.com/,
new workbox.strategies.NetworkFirst(),
'GET'
);
workbox.routing.registerRoute(
'https://myapp.com/posts',
new workbox.strategies.NetworkFirst(),
'GET'
);
workbox.routing.registerRoute(
'https://myapp.com/favorites',
new workbox.strategies.NetworkFirst(),
'GET'
);
workbox.routing.registerRoute(
/^http/,
new workbox.strategies.StaleWhileRevalidate(),
'GET'
);
/*
posts queue
*/
// *** I ONLY WANT TO RUN THIS CODE IF BACKGROUND SYNC IS SUPPORTED ***
const postsQueue = new workbox.backgroundSync.Queue('postsQueue', {
maxRetentionTime: 24 * 60 * 365, // Retry for max of one year
onSync: async ({queue}) => {
let entry;
while (entry = await queue.shiftRequest()) {
try {
await fetch(entry.request);
// console.log('Replay successful for request', entry.request);
const clients = await self.clients.matchAll({type: 'window'});
for (const client of clients) {
client.postMessage({
msg: "offline-post-uploaded"
})
}
} catch (error) {
console.error('Replay failed for request', entry.request, error);
// Put the entry back in the queue and re-throw the error:
await queue.unshiftRequest(entry);
throw error;
}
}
// console.log('Replay complete!');
}
})
/*
update post queue
*/
// *** I ONLY WANT TO RUN THIS CODE IF BACKGROUND SYNC IS SUPPORTED ***
const updatePostQueue = new workbox.backgroundSync.Queue('updatePostQueue', {
maxRetentionTime: 24 * 60 * 365, // Retry for max of one year
onSync: async ({queue}) => {
let entry;
while (entry = await queue.shiftRequest()) {
try {
await fetch(entry.request);
console.log('Replay successful for request', entry.request);
} catch (error) {
console.error('Replay failed for request', entry.request, error);
// Put the entry back in the queue and re-throw the error:
await queue.unshiftRequest(entry);
throw error;
}
}
// console.log('Replay complete!');
}
})
/*
events
*/
// *** I ONLY WANT TO RUN THIS CODE IF BACKGROUND SYNC IS SUPPORTED ***
self.addEventListener('fetch', (event) => {
// console.log('event.request.url: ', event.request.url)
if (event.request.url == 'https://myapp.com/createPost') {
console.log('SW fetch createPost')
// Clone the request to ensure it's safe to read when
// adding to the Queue.
if (!self.navigator.onLine) {
console.log('SW device is offline')
const promiseChain = fetch(event.request.clone()).catch((err) => {
return postsQueue.pushRequest({request: event.request});
});
event.waitUntil(promiseChain);
}
else {
console.log('SW device is online')
}
}
else if (event.request.url.startsWith('https://myapp.com/updatePost')) {
// Clone the request to ensure it's safe to read when
// adding to the Queue.
if (!self.navigator.onLine) {
const promiseChain = fetch(event.request.clone()).catch((err) => {
return updatePostQueue.pushRequest({request: event.request});
});
event.waitUntil(promiseChain);
}
}
});
self.addEventListener('notificationclick', event => {
let notification = event.notification
let action = event.action
event.waitUntil(
clients.matchAll()
.then(clis => {
let client = clis.find(cli => {
return cli.visibilityState === 'visible'
})
if (client !== undefined) {
client.navigate(notification.data.openUrl)
client.focus()
}
else {
clients.openWindow(notification.data.openUrl)
}
// notification.close()
})
)
})
self.addEventListener('notificationclose', event => {
console.log('Notification was closed', event)
})
self.addEventListener('push', event => {
console.log('Push Notification received: ', event)
if (event.data) {
console.log('event.data: ', event.data)
let data = JSON.parse(event.data.text())
console.log('data: ', data)
console.log('showNotificationYo!')
event.waitUntil(
self.registration.showNotification(
data.title,
{
body: data.body,
icon: 'statics/icons/icon-128x128.png',
badge: 'statics/icons/icon-128x128.png',
image: data.imageUrl,
data: {
openUrl: data.openUrl
}
}
)
)
}
})