close

本文章包含
 詳盡流程圖介紹
 金鑰產生
 使用serviceworker
 推播功能實現
 常見問題

完整流程圖

 

網頁推播完整流程

金鑰產生

如流程圖步驟,為了讓網頁向推播伺服器取得token,再讓伺服器依據token發送推播,必須事先產生「金鑰」
金鑰產生網址:Google官方文件指定連結
您可能會搜尋到一些文章說明使用「vapid」或「openssl」產生金鑰,這裡暫時不討論。

 

Service Worker

為了讓網頁能接收通知,必須使用「Service Worker」技術在背景執行程式,以下注意事項:
 必須使用https,但在localhost開發測試階段可暫不使用
 js腳本必須存在於根目錄
 

  1. 註冊service worker (根目錄下使用sw.js,檔名可更改,但必須在根目錄下)
      navigator.serviceWorker.register('./sw.js').then(function(swReg) {
      swReg.pushManager.getSubscription()
      .then(function(subscription) {
      if(subscription != null) {
      // register succeed
      }
      })//then
      })//then
      .catch(function(error) {
      console.error('Service Worker Error', error);
      });
    view rawregister-sw.js hosted with ❤ by GitHub
  2. 將sw.js放置於根目錄,處理推播事件
      // 監聽推播事件
      self.addEventListener('push', function(event) {
      var data = {
      "message":"[無法讀取訊息]"
      }
      try {
      data = event.data.json();
      } catch(e) {}
       
      var title = '您有新訊息';
      var body = data.message;
      var icon = '/img/icon.png';
      var tag = '';
       
      event.waitUntil(
      self.registration.showNotification(title, {
      body: body,
      icon: icon,
      tag: tag
      })
      );
      });
       
      // 使用者點擊推播彈跳訊息
      self.addEventListener('notificationclick', function(event) {
      var goingToOpenUrl = 'https://example.com';
      event.notification.close();
       
      event.waitUntil(clients.matchAll({
      type: 'window'
      }).then(function(clientList) {
      for (var i = 0; i < clientList.length; i++) {
      var client = clientList[i];
      if (client.url === goingToOpenUrl && 'focus' in client) {
      return client.focus();
      }
      }
      if (clients.openWindow) {
      return clients.openWindow(goingToOpenUrl);
      } else {
      console.log("無法開啟url:"+goingToOpenUrl);
      }
      }));
      });
    view rawsw.js hosted with ❤ by GitHub

 

 

實現推播功能

在註冊了service worker之後,就可以向推播伺服器進行註冊:

  1. 向推播伺服器註冊取得subscription(json object,包括 endpoint/p256dh/auth)
      // applicationServerPublicKey generated from https://web-push-codelab.glitch.me/
      // swReg get from `navigator.serviceWorker.register('./sw.js').then`
      const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
      swReg.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: applicationServerKey
      })
      .then(function(subscription) {
      // subscribed succeed
      // sent subscription to server
      })
      .catch(function(err) {
      console.log('Failed to subscribe the user: ', err);
      });
       
      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 (var i = 0; i < rawData.length; ++i) {
      outputArray[i] = rawData.charCodeAt(i);
      }
      return outputArray;
      }
    view rawsubscribe-push.js hosted with ❤ by GitHub
  2. 將subscription傳送給後台
  3. 後台發送推播。
    至於如何使用後台發送推播,在github上有許多library:
    python
    node.js
    php
    java
    c#
    web-push-libs

 

 

常見問題

  • Q: 在sw.js收到推播事件「event」時沒有data參數


    A: 這可能是因為您在向推播伺服器註冊時沒有夾帶「applicationServerKey」,如此一來推播時就不會夾帶您傳送的data

  • Q: Firefox可以順利接收推播,但是在chrome卻有異常


    A: 這可能是因為您先前向推播伺服器註冊註冊時沒有夾帶「applicationServerKey」,而後來又再次註冊並夾帶「applicationServerKey」導致的異常。首先在chrome點擊右鍵->選擇檢查->打開「Application」分頁->點選Service Workers->點擊Upload on reload或unregister,並再次註冊即可。

  • Q: 後端伺服器發送推播時出現異常


    A: 這可能是因為您使用的 public key 與 private key的異常,請參考「金鑰產生」步驟引導的產生方式。

 

參考連結

Google官方文件連結

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 codus 的頭像
    codus

    codus的部落格

    codus 發表在 痞客邦 留言(0) 人氣()