Web 应用推送通知,无法在浏览器上推送通知

Posted

技术标签:

【中文标题】Web 应用推送通知,无法在浏览器上推送通知【英文标题】:Web App Push Notification, Unable to Push the notification on browser 【发布时间】:2018-11-05 11:55:25 【问题描述】:

我一直在尝试在我的网络应用上推送通知。 我一直在关注google's codelabs 寻求帮助,我一直很成功,直到我到达“处理推送事件”部分。 我完全按照他们所说的做了,我哪里可能出错? 我是新手,所以请提前帮助并感谢所有愿意回答的人

我的主要脚本代码如下:

    'use strict';

const applicationServerPublicKey = 'BEEbOQcOmPNlAHvkHCdVGPehs3y45L-30_71yyrRbxNRp7Q3bCEGWoCnq5dxeiB2nwGWfTc5BOrbEWsU2FGXgtk';

const pushButton = document.querySelector('.js-push-btn');

let isSubscribed = false;
let swRegistration = null;

function urlB64ToUint8Array(base64String) 
  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  const base64 = (base64String + padding)
    .replace(/\-/g, '+')
    .replace(/_/g, '/');

  const rawData = window.atob(base64);
  const outputArray = new Uint8Array(rawData.length);

  for (let i = 0; i < rawData.length; ++i) 
    outputArray[i] = rawData.charCodeAt(i);
  
  return outputArray;


if ('serviceWorker' in navigator && 'PushManager' in window) 
  console.log('Service Worker and Push is supported');

  navigator.serviceWorker.register('sw.js')
  .then(function(swReg) 
    console.log('Service Worker is registered', swReg);

    swRegistration = swReg;
  )
  .catch(function(error) 
    console.error('Service Worker Error', error);
  );
 else 
  console.warn('Push messaging is not supported');
  pushButton.textContent = 'Push Not Supported';


function initializeUI() 
    pushButton.addEventListener('click', function() 
    pushButton.disabled = true;
    if (isSubscribed) 
      // TODO: Unsubscribe user
     else 
      subscribeUser();
    
  );

  // Set the initial subscription value
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) 
    isSubscribed = !(subscription === null);

    if (isSubscribed) 
      console.log('User IS subscribed.');
     else 
      console.log('User is NOT subscribed.');
    

    updateBtn();
  );


function updateBtn() 
  if (Notification.permission === 'denied') 
    pushButton.textContent = 'Push Messaging Blocked.';
    pushButton.disabled = true;
    updateSubscriptionOnServer(null);
    return;
  


  if (isSubscribed) 
    pushButton.textContent = 'Disable Push Messaging';
   else 
    pushButton.textContent = 'Enable Push Messaging';
  

  pushButton.disabled = false;


function subscribeUser() 
  const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
  swRegistration.pushManager.subscribe(
    userVisibleOnly: true,
    applicationServerKey: applicationServerKey
  )
  .then(function(subscription) 
    console.log('User is subscribed.');

    updateSubscriptionOnServer(subscription);

    isSubscribed = true;

    updateBtn();
  )
  .catch(function(err) 
    console.log('Failed to subscribe the user: ', err);
    updateBtn();
  );


function updateSubscriptionOnServer(subscription) 
  // TODO: Send subscription to application server

  const subscriptionJson = document.querySelector('.js-subscription-json');
  const subscriptionDetails =
    document.querySelector('.js-subscription-details');

  if (subscription) 
    subscriptionJson.textContent = JSON.stringify(subscription);
    subscriptionDetails.classList.remove('is-invisible');
   else 
    subscriptionDetails.classList.add('is-invisible');
  


navigator.serviceWorker.register('sw.js')
.then(function(swReg) 
  console.log('Service Worker is registered', swReg);

  swRegistration = swReg;
  initializeUI();
)

我的 sw.js 代码是

'use strict';
self.addEventListener('push', function(event) 
  console.log('[Service Worker] Push Received.');
  console.log(`[Service Worker] Push had this data: "$event.data.text()"`);

  const title = 'Push Codelab';
  const options = 
    body: 'Yay it works.',
    icon: 'images/icon.png',
    badge: 'images/badge.png'
  ;

  event.waitUntil(self.registration.showNotification(title, options));
);

我在控制台中收到以下错误消息:

由于附加了 DevTools,Service Worker 因超时计时器而终止。

【问题讨论】:

请添加代码 完成。 @Felipe Morales 【参考方案1】:
    'use strict';

const applicationServerPublicKey = 'BKqJnZ7e-r7DMOqpx2mm-BCWDCm1Urvt2KnwwmFe7v5QEfMMl139SlNGi6T6FSUmcNVJhXEI6_uLiauw1AFuMJc';
//BKqJnZ7e+r7DMOqpx2mm+BCWDCm1Urvt2KnwwmFe7v5QEfMMl139SlNGi6T6FSUmcNVJhXEI6/uLiauw1AFuMJc=
const pushButton = document.querySelector('.js-push-btn');

let isSubscribed = false;
let swRegistration = null;

function urlB64ToUint8Array(base64String) 

  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  //console.log(padding + base64String.length);
  const base64 = (base64String + padding)
    .replace(/\-/g, '+')
    .replace(/_/g, '/');
  const rawData = window.atob(base64);
  //console.log(base64);
  //console.log(rawData);
  const outputArray = new Uint8Array(rawData.length);
  for (let i = 0; i < rawData.length; ++i) 
  
    outputArray[i] = rawData.charCodeAt(i);
  
  console.log(outputArray);
  return outputArray;


//1
if ('serviceWorker' in navigator && 'PushManager' in window) 

  console.log('Service Worker and Push is supported');

  navigator.serviceWorker.register('sw.js').then
  (
    function(swReg) 
    
      //console.log(swReg);
      console.log('Service Worker is registered', swReg);

      swRegistration = swReg;

      //console.log(swRegistration);
    
  )
  .catch
  (
    function(error) 
    
      console.error('Service Worker Error', error);
    
  );
 
else 

  console.warn('Push messaging is not supported');
  pushButton.textContent = 'Push Not Supported';


//2
function updateBtn() 

  if (Notification.permission === 'denied') 
  
    pushButton.textContent = 'Push Messaging Blocked.';
    pushButton.disabled = true;
    updateSubscriptionOnServer(null);
    return;
  
  if (isSubscribed) 
  
    pushButton.textContent = 'Disable Push Messaging';
   
  else 
  
    pushButton.textContent = 'Enable Push Messaging';
  
  pushButton.disabled = false;


navigator.serviceWorker.register('sw.js').then
(
  function(swReg)
  
    console.log('Service Worker is registered', swReg);
    swRegistration = swReg;
    initializeUI();
  
)

//3
function initializeUI() 

  pushButton.addEventListener
  (
    'click', function() 
    
      pushButton.disabled = true;
      if (isSubscribed) 
      
        unsubscribeUser();
       
      else 
      
        subscribeUser();
      
    
  );
  // Set the initial subscription value
  swRegistration.pushManager.getSubscription().then
  (
    function(subscription) 
    
      isSubscribed = !(subscription === null);
      updateSubscriptionOnServer(subscription);
      if (isSubscribed) 
      
        console.log('User IS subscribed.');
       
      else 
      
        console.log('User is NOT subscribed.');
      
      updateBtn();
    
  );


//4
function subscribeUser() 

  const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
  swRegistration.pushManager.subscribe
  (
    
      userVisibleOnly: true,
      applicationServerKey: applicationServerKey
    
  )
  .then
  (
    function(subscription) 
    
      console.log('User is subscribed.');

      updateSubscriptionOnServer(subscription);

      isSubscribed = true;

      updateBtn();
    
  )
  .catch
  (
    function(err) 
    
      console.log('Failed to subscribe the user: ', err);
      updateBtn();
    
  );


//5
function updateSubscriptionOnServer(subscription) 

  // TODO: Send subscription to application server

  const subscriptionJson = document.querySelector('.js-subscription-json');
  const subscriptionDetails = document.querySelector('.js-subscription-details');
  if (subscription) 
  
    subscriptionJson.textContent = JSON.stringify(subscription);
    subscriptionDetails.classList.remove('is-invisible');
   
  else 
  
    subscriptionDetails.classList.add('is-invisible');
  


//6
function unsubscribeUser() 
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) 
    if (subscription) 
      return subscription.unsubscribe();
    
  )
  .catch(function(error) 
    console.log('Error unsubscribing', error);
  )
  .then(function() 
    updateSubscriptionOnServer(null);

    console.log('User is unsubscribed.');
    isSubscribed = false;

    updateBtn();
  );

【讨论】:

虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释并说明适用的限制和假设。

以上是关于Web 应用推送通知,无法在浏览器上推送通知的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Web 推送库上使用推送通知服务?

Java Web应用程序的推送通知[关闭]

无法从 Parse 仪表板发送推送通知

打开推送通知时无法刷新我的 web 视图

如何将推送通知发送到Web浏览器?

让 HTML5 推送通知适用于所有 Web 浏览器和移动浏览器?