本文章包含
詳盡流程圖介紹
金鑰產生
使用serviceworker
推播功能實現
常見問題
完整流程圖
金鑰產生
如流程圖步驟,為了讓網頁向推播伺服器取得token,再讓伺服器依據token發送推播,必須事先產生「金鑰」
金鑰產生網址:Google官方文件指定連結
您可能會搜尋到一些文章說明使用「vapid」或「openssl」產生金鑰,這裡暫時不討論。
Service Worker
為了讓網頁能接收通知,必須使用「Service Worker」技術在背景執行程式,以下注意事項:
必須使用https,但在localhost開發測試階段可暫不使用
js腳本必須存在於根目錄
- 註冊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); |
|
}); |
- 將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); |
|
} |
|
})); |
|
}); |
實現推播功能
在註冊了service worker之後,就可以向推播伺服器進行註冊:
- 向推播伺服器註冊取得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; |
|
} |
- 將subscription傳送給後台
- 後台發送推播。
至於如何使用後台發送推播,在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官方文件連結
留言列表