Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 等待ServiceWorker完成注册后再订阅_Javascript_Google Chrome_Push Notification_Service Worker - Fatal编程技术网

Javascript 等待ServiceWorker完成注册后再订阅

Javascript 等待ServiceWorker完成注册后再订阅,javascript,google-chrome,push-notification,service-worker,Javascript,Google Chrome,Push Notification,Service Worker,我正在使用ServiceWorker实现用户通知。当用户首次访问站点并批准通知时,ServiceWorker将注册并订阅: if ('serviceWorker' in navigator) { console.log('Service Worker is supported'); navigator.serviceWorker.register('/js/sw.js').then(function(reg) { if(/chrom(e|ium)/.test(navigator.use

我正在使用ServiceWorker实现用户通知。当用户首次访问站点并批准通知时,ServiceWorker将注册并订阅:

if ('serviceWorker' in navigator) {
 console.log('Service Worker is supported');
 navigator.serviceWorker.register('/js/sw.js').then(function(reg) {
   if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){
       reg.pushManager.subscribe({
           userVisibleOnly: true
       }).then(function(sub) {
           console.log('endpoint:', sub.endpoint);
           endpoint = sub.endpoint;
           fetch(MY_API+encodeURIComponent(endpoint), {
                    credentials: 'include'
                 })
       });
   }
 }).catch(function(err) {
   console.log(':^(', err);
 });
}
在第一次访问时,这失败于:

Uncaught (in promise) DOMException: Subscription failed - no active Service Worker
从第二次访问开始,一切都正常,因为当时ServiceWorker已经处于活动状态。看来这是个时间问题。在尝试订阅之前,如何确保ServiceWorker已成功注册并处于活动状态

我尝试使用
navigator.serviceWorker.ready
,建议如下:

if ('serviceWorker' in navigator) {
 console.log('Service Worker is supported');
 navigator.serviceWorker.register('/js/sw.js').then(function(sreg) {
   console.log(':^)', sreg);
   navigator.serviceWorker.ready.then(function(reg) {
       if(/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){
           reg.pushManager.subscribe({
               userVisibleOnly: true
           }).then(function(sub) {
               console.log('endpoint:', sub.endpoint);
               endpoint = sub.endpoint;
               fetch("https://www.wettfreun.de/?page=fetch&s=1&endpoint="+encodeURIComponent(endpoint), {credentials: 'include'})
           });
       }
   });
 }).catch(function(err) {
   console.log(':^(', err);
 });
}
现在,
navigator.serviceWorker.ready.then()中的部分永远不会被调用。

您可以使用

示例来自:


为什么你只在Chrome/Chrome上使用推送API?因为我的后端目前只支持GCM,没有有效负载,所以Web推送标准很容易实现(基本上是对端点URL的POST请求)。你能举个例子吗?您提供的文档中没有注册。ready()调用应该在哪里进行?我在MDN中添加了一个示例。啊,也许您还想知道如何在第一次加载页面时激活服务工作者?看看。谢谢Marco,我已经在服务工作者的安装侦听器中调用了skipWaiting()。正如我所说,MDN中的示例不包括服务工作者注册(只有订阅过程,服务工作者已经在前面注册)。也许这是出于设计,我们不应该在页面加载时启动订阅过程,而应该在用户交互时启动订阅过程。您是否也可以调用?这不是设计的,我是在我的一个项目中加载并等待就绪后订阅的,它可以正常工作。
function subscribe() {
  var subscribeButton = document.querySelector('.js-subscribe-button');
  subscribeButton.disabled = false;

  navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    serviceWorkerRegistration.pushManager.subscribe()
      .then(function(subscription) {
        // The subscription was successful
        subscribeButton.disabled = true;
        return sendSubscriptionToServer(subscription);
      })
      .catch(function(error) {
        if (Notification.permission === 'denied') {
          console.log('Permission for Notifications was denied');
          subscribeButton.disabled = true;
        } else {
          console.log('Unable to subscribe to push.', error);
          subscribeButton.disabled = false;
        }
      });
  });
}