Как я могу определить, есть ли у клиента поддержка Background Syn c от Service Worker? - PullRequest
0 голосов
/ 27 марта 2020

Как я могу определить, имеет ли браузер пользователя поддержку 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
          }
        }
      )
    )
  }
})

1 Ответ

1 голос
/ 31 марта 2020

Функция обнаружения , используемая в workbox-background-sync, выглядит следующим образом:

if ('sync' in self.registration) {
  // Background sync is natively supported.
}

Вы можете сделать что-то подобное в своем собственном коде, чтобы определить встроенную поддержку.

...