首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何检测客户端是否具有来自服务工作人员的后台同步支持?

如何检测客户端是否具有来自服务工作人员的后台同步支持?
EN

Stack Overflow用户
提问于 2020-03-27 10:48:43
回答 1查看 887关注 0票数 1

如何检测用户的浏览器是否在服务工作者中具有来自的后台同步支持

我知道如何在应用程序端检测这一点,但不是从服务工作者本身。

基本上,我使用的是工作盒的背景同步,而且在Chrome和Chrome Mobile中都很好用。

我知道Workbox对于不支持后台同步的浏览器有一个后台同步“回退”,但这不是很好,所以我宁愿完全禁用不支持它的浏览器的后台同步。

这是我的服务人员档案供参考。您可以看到,如果浏览器不支持后台同步,我不希望执行3块代码(我用*** I ONLY WANT TO RUN THIS CODE IF BACKGROUND SYNC IS SUPPORTED ***标记了这些代码):

代码语言:javascript
运行
复制
/*
 * 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
          }
        }
      )
    )
  }
})
EN

Stack Overflow用户

回答已采纳

发布于 2020-03-31 19:39:18

特征检测中使用的workbox-background-sync如下所示:

代码语言:javascript
运行
复制
if ('sync' in self.registration) {
  // Background sync is natively supported.
}

您可以在自己的代码中执行类似的操作来确定本机支持。

票数 3
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60884486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档