未捕获(在promise中)DOM异常:订阅失败-没有活动的Service Worker

15

我正在尝试订阅用户,但第一次出现了以下错误。 第二次就可以运作了,因为用户已经激活。

这是我的代码:

 if ('serviceWorker' in navigator) {
   console.log('Service Worker is supported');
   navigator.serviceWorker.register('sw.js').then(function(reg) {
     console.log(':^)', reg);
     reg.pushManager.subscribe({
       userVisibleOnly: true
     }).then(function(sub) {
       console.log('endpoint:', sub.endpoint);
       var div = document.getElementById('id');
       div.innerHTML = div.innerHTML + sub.endpoint;
       // var b = document.getElementsByTagName('body')[0];
       //b.appendChild(div);
       //alert(sub.endpoint);
     });
   });
 }

我已经尝试了以下方法,但ready.then()方法没有执行:

 if ('serviceWorker' in navigator) {
   console.log('Service Worker is supported');
   navigator.serviceWorker.register('sw.js').then(function(sreg) {
     console.log(':^)', sreg);
     navigator.serviceWorker.ready.then(function(reg) {
       reg.pushManager.subscribe({
         userVisibleOnly: true
       }).then(function(sub) {
         console.log('endpoint:', sub.endpoint);
         var div = document.getElementById('id');
         div.innerHTML = div.innerHTML + sub.endpoint;
         // var b = document.getElementsByTagName('body')[0];
         //b.appendChild(div);
         //alert(sub.endpoint);
       });
     });
   });
 }

有什么想法吗?

2个回答

18

在触发订阅之前,您应该等待服务工作者被激活。

使用stateChange监听器来确定服务工作者是否处于活动状态。

navigator.serviceWorker.register(workerFileName, {scope: "/"})
    .then(
    function (reg) {
        var serviceWorker;
        if (reg.installing) {
            serviceWorker = reg.installing;
            // console.log('Service worker installing');
        } else if (reg.waiting) {
            serviceWorker = reg.waiting;
            // console.log('Service worker installed & waiting');
        } else if (reg.active) {
            serviceWorker = reg.active;
            // console.log('Service worker active');
        }

        if (serviceWorker) {
            console.log("sw current state", serviceWorker.state);
            if (serviceWorker.state == "activated") {
                //If push subscription wasnt done yet have to do here
                console.log("sw already activated - Do watever needed here");
            }
            serviceWorker.addEventListener("statechange", function(e) {
                console.log("sw statechange : ", e.target.state);
                if (e.target.state == "activated") {
                    // use pushManger for subscribing here.
                    console.log("Just now activated. now we can subscribe for push notification")
                    subscribeForPushNotification(reg);
                }
            });
        }
    },
    function (err) {
        console.error('unsuccessful registration with ', workerFileName, err);
    }
);

7
您可以通过检查服务工作者状态来解决此问题。只有在服务工作者处于活动状态时才执行您的操作。
navigator.serviceWorker.register('sw.js').then(function(reg) {
 if(reg.installing) {
        console.log('Service worker installing');
    } else if(reg.waiting) {
        console.log('Service worker installed');
    } else if(reg.active) {
        console.log('Service worker active');
    }
 // Include below mentioned validations
}

使用以下方法检查是否支持推送通知:

 // Check if push messaging is supported  
    if (!('PushManager' in window)) {  
       console.log('Push messaging isn\'t supported.');  
       return;  
     }
   //
   if (Notification.permission === 'denied') {  
      console.log('The user has blocked notifications.');  
      return;  
   }

在实施这两个检查后,实现您的功能。
navigator.serviceWorker.ready.then(function(reg) {  .... })

希望这能有所帮助。

但它仍然没有注册用户,这是我的问题。 - user6609184
这个 console.log(':^)', reg); 是否被打印出来了? - bvakiti
你能否检查一下没有Push Manager的代码是否正常运行? - bvakiti
将 reg.pushManager.subscribe({ 代码注释掉,然后检查它是否正常工作即可。 - bvakiti
尝试为serviceWorker.register方法设置范围。请查看我的代码@https://github.com/bandhavya/bandhavya.github.io 我没有包括pushManager。 - bvakiti
如果我没有被理解,我想要获取注册用户的端点,因为软件尚未激活,所以它给了我这个错误。 - user6609184

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接