摘要:在端,盡管開發(fā)人員對其功能的需求很高,但出于某些原因,推送通知被引入的時間比較晚。發(fā)送推送通知在服務(wù)器上實現(xiàn)調(diào)用,該調(diào)用觸發(fā)到用戶設(shè)備的推送消息。推送服務(wù)推送服務(wù)是接收請求驗證請求并將推送消息發(fā)送到對應(yīng)的瀏覽器。
這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第9篇。
想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!
如果你錯過了前面的章節(jié),可以在這里找到它們:
JavaScript是如何工作的:引擎,運行時和調(diào)用堆棧的概述!
JavaScript是如何工作的:深入V8引擎&編寫優(yōu)化代碼的5個技巧!
JavaScript如何工作:內(nèi)存管理+如何處理4個常見的內(nèi)存泄漏 !
JavaScript是如何工作的:事件循環(huán)和異步編程的崛起+ 5種使用 async/await 更好地編碼方式!
JavaScript是如何工作: 深入探索 websocket 和HTTP/2與SSE +如何選擇正確的路徑!
JavaScript是如何工作的:與 WebAssembly比較 及其使用場景 !
JavaScript是如何工作的:Web Workers的構(gòu)建塊+ 5個使用他們的場景
JavaScript 是如何工作的:Service Worker 的生命周期及使用場景
推送通知在移動端非常常見。在 Web 端,盡管開發(fā)人員對其功能的需求很高,但出于某些原因,推送通知被引入 Web 的時間比較晚。
簡介Web 推送通知允許用戶在 Web 應(yīng)用程序需要更新時選擇是否接收更新消息,目的是在重新吸引用戶群注意的更新信息通常是對用戶來說有趣、重要、實時的內(nèi)容。
推送通知的基礎(chǔ)是我們 上一篇 講的 Service Workers。
在這種情況下,使用 Service Worker 的原因是它們在后臺工作。這對于推送通知非常有用,因為這意味著只有當(dāng)用戶與通知本身進行交互時,它們的代碼才會被執(zhí)行。
推送和通知推送和通知都有各自的 API
推送 —?當(dāng)服務(wù)器向 Service Worker 提供信息時調(diào)用它。
通知 — 這是 Service Worker 或web應(yīng)用程序中向用戶顯示信息的腳本的操作。
推送 ( Push )實現(xiàn) Push 一般的三個步驟:
UI — 添加必要的客戶端邏輯來訂閱推送的用戶。這是 Web 應(yīng)用程序 UI 需要的 JavaScript 邏輯,以便用戶能夠自己注冊來推送消息。
發(fā)送推送通知 — 在服務(wù)器上實現(xiàn) API 調(diào)用,該調(diào)用觸發(fā)到用戶設(shè)備的推送消息。
接受推送消息 — 在推送消息到達瀏覽器時處理它。
接下來討論更詳細的過程。
瀏覽器支持檢測首先,我們需要檢查當(dāng)前瀏覽器是否支持推送消息,可以通過兩個簡單的檢查來判斷是否支持推送消息:
檢查 navigator 對象上的 serviceWorker
檢查 window 對象上的 PushManager
代碼如下:
注冊 Service Worker如果瀏覽器支持該功能,下一步驟就是注冊 Service Worker。
如何注冊 Service Worker,上一篇文章 JavaScript 是如何工作的:Service Worker 的生命周期及使用場景 里面就有講過了。
請求許可Service Worker 注冊后,我們就可以開始訂閱該用戶。為此,我們需要得到用戶的許可才能給用戶發(fā)送推送消息。
獲得權(quán)限的 API 相對簡單,但是缺點是,API 已經(jīng) 從回調(diào)更改為返回 Promise。這就引入了一個問題:我們不知道當(dāng)前瀏覽器實現(xiàn)了 API 的哪個版本,因此必須同時實現(xiàn)和處理這兩個版本,如下:
調(diào)用 Notification.requestpermission() 會在瀏覽器顯示如下提示:
一旦權(quán)限被授予、關(guān)閉或阻塞,我們將會接收分別對應(yīng)的一個字符串:granted、default 或 denied。
請記住,如果用戶單擊了 Block 按鈕,你的 Web 應(yīng)用程序?qū)o法再次請求用戶的權(quán)限,直到他們通過更改權(quán)限狀態(tài)手動 “解除” 你的應(yīng)用程序的權(quán)限,此選項隱藏在設(shè)置面板中。
使用 PushManager 訂閱用戶一旦注冊了 Service Worker 并獲得了許可,就可以在注冊 Service Worker 時通過調(diào)用registration.pushManager.subscribe() 訂閱用戶。
整個代碼片段可如下(包括注冊 Service Worker):
registration.pushManager.subscribe(options) 接受一個 options 對象,它包含必要參數(shù)和可選參數(shù):
userVisibleOnly: 布爾值,表示返回的推送訂閱將只能被用于對用戶可見的消息。
applicationServerKey:推送服務(wù)器用來向客戶端應(yīng)用發(fā)送消息的公鑰。該值是應(yīng)用程序服務(wù)器生成的簽名密鑰對的一部分,可使用在 P-256 曲線上實現(xiàn)的橢圓曲線數(shù)字簽名(ECDSA)??梢允?DOMString 或 ArrayBuffer。
你的服務(wù)器需要生成一對 application server keys?——這些密鑰也稱為 VAPID 密鑰,它們是服務(wù)器特有的。它們是一對公鑰和私鑰。私鑰秘密存儲在你的終端,而公鑰則與客戶端交換。這些鍵允許推送服務(wù)知道哪個應(yīng)用服務(wù)器訂閱了某個用戶,并確保觸發(fā)該用戶的推送消息的服務(wù)器是同一臺服務(wù)器。
你只需要為應(yīng)用程序創(chuàng)建一次 私鑰/公鑰對,一種方法是訪問 https://web-push-codelab.glit...。
在訂閱用戶時,瀏覽器將 applicationServerKey(公共密鑰)傳遞給推送服務(wù),這意味著推送服務(wù)可以將應(yīng)用程序的公共密鑰綁定到用戶的 PushSubscription 。
流程大概是這樣的:
加載 Web 應(yīng)用程序后,通過調(diào)用 subscribe()方法傳遞服務(wù)器密鑰。
瀏覽器向一個推送服務(wù)發(fā)出網(wǎng)絡(luò)請求,該服務(wù)將生成一個端點,將該端點與密鑰關(guān)聯(lián),并將該端點返回給瀏覽器。
瀏覽器將把這個端點添加到 PushSubscription 對象中,該對象通過 返回 subscribe() 的 promise 得到 。
之后,只要你想推送消息,都需要創(chuàng)建一個 授權(quán)頭(Authorization header),其中包含使用應(yīng)用服務(wù)器的私鑰簽名的信息。當(dāng)推送服務(wù)接收到發(fā)送推送消息的請求時,它將通過查找已鏈接到該特定端點的公鑰(第二步)來驗證消息頭。
PushSubscription 對象PushSubscription 對象包含向用戶的設(shè)備發(fā)送推送消息所需的所有信息,如下:
{ "endpoint": "https://domain.pushservice.com/some-id", "keys": { "p256dh": "BIPUL12DLfytvTajnryr3PJdAgXS3HGMlLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WArAPIxr4gK0_dQds4yiI=", "auth":"FPssMOQPmLmXWmdSTdbKVw==" } }
endpoint: 推送服務(wù)的 URL,要觸發(fā)推送消息,post請求。
keys: 該對象包含用于加密通過推送消息發(fā)送的消息數(shù)據(jù)的值。
一旦用戶被訂閱,并且你有了 PushSubscription 對象,就需要將其發(fā)送到服務(wù)器。在服務(wù)器上,你存對數(shù)據(jù)庫的訂閱,從現(xiàn)在開始使用它向該用戶發(fā)送推送消息。
發(fā)送推送消息當(dāng)你想向用戶發(fā)送推送消息時,首先需要的是推送服務(wù)。通過 API 調(diào)用告訴服務(wù)器你現(xiàn)在需要要發(fā)送什么數(shù)據(jù)、向誰發(fā)送消息以及關(guān)于如何發(fā)送消息的任何標(biāo)準(zhǔn)。通常,這個 API 調(diào)用是在服務(wù)器上完成的。
推送服務(wù)推送服務(wù)是接收請求、驗證請求并將推送消息發(fā)送到對應(yīng)的瀏覽器。
請注意,推送服務(wù)不是由你管理的——它是一個第三方服務(wù)。你的服務(wù)器是通過 API 與 推送服務(wù)通信的服務(wù)器。推送服務(wù)的一個例子是 谷歌的FCM。
推送服務(wù)處理所有繁重的任務(wù),比如,如果瀏覽器處于脫機狀態(tài),推送服務(wù)會在發(fā)送相應(yīng)消息之前對消息進行排隊,等待瀏覽器的再次聯(lián)機。
每個瀏覽器都可以使用他們想要的任何推送服務(wù),這是開發(fā)人員無法控制的。然而,所有的推送服務(wù)都有相同的 Api,所以這不會造成實現(xiàn)困難。
為了獲得處理推送消息請求的 URL,需要檢查 PushSubscription 對象中端點的存儲值。
推送服務(wù) API推送服務(wù) API 提供了一種向用戶發(fā)送消息的方法。API 是 Web 協(xié)議,它是一個 IETF 標(biāo)準(zhǔn),定義了如何對推送服務(wù)進行 API 調(diào)用。
使用推送消息發(fā)送的數(shù)據(jù)必須加密。這樣,就可以阻止推送服務(wù)查看發(fā)送的數(shù)據(jù)。這一點很重要,因為瀏覽器決定使用哪個推送服務(wù)(它可能正在使用不受信任且不夠安全的某個推送服務(wù))。
對于每條推送消息,也可以給出如下說明:
TTL ?— 定義消息在刪除和未發(fā)送之前應(yīng)排隊多長時間。
優(yōu)先級 — 定義每個消息的優(yōu)先級,推送服務(wù)只發(fā)送高優(yōu)先級的消息,確保用戶因為一些突發(fā)情況關(guān)機或者斷電等。
主題 — 為推送消息提供一個主題名稱,該名稱將用相同的主題替換掛起的消息,這樣,一旦設(shè)備處于活動狀態(tài),用戶就不會收到過時的信息。
瀏覽器中的推送事件一旦按照上面的解釋將消息發(fā)送到推送服務(wù),該消息將處于掛起狀態(tài),直到發(fā)生以下情況之一:
設(shè)備上線
消息由于 TTL 而在隊列上過期
當(dāng)推送服務(wù)傳遞消息時,瀏覽器將接收它,解密它,并在的 Service Worker 中分派一個 push 事件。這里最重要的是,即使 Web 頁面沒有打開,瀏覽器也可以執(zhí)行你的 Service Worker。流程如下:
推送消息到達瀏覽器,瀏覽器解密它
瀏覽器喚醒 Service Worker
push 事件被分發(fā)給 Service Worker
設(shè)置推送事件監(jiān)聽器的代碼應(yīng)該與用 JavaScript 編寫的任何其他事件監(jiān)聽器類似:
self.addEventListener("push", function(event) { if (event.data) { console.log("This push event has data: ", event.data.text()); } else { console.log("This push event has no data."); } });
需要了解 Service Worker 的一點是,你沒有 Service Worker 代碼運行時長的控制權(quán)。瀏覽器決定何時將其喚醒以及何時終止它。
在 Service Worker 中,event.waitUntil(promise),告訴瀏覽器在該promse 未完成之前工作將一直進行中,如果它希望完成該工作,它不應(yīng)該終止 Sercice Worker。
以下是一個處理 push 事件的例子:
self.addEventListener("push", function(event) { var promise = self.registration.showNotification("Push notification!"); event.waitUntil(promise); });
調(diào)用 self.registration.showNotification() 將向用戶顯示一個通知,并返回一個 promise,該 promise 在顯示通知后將執(zhí)行 resolve 方法。
showNotification(title, options) 方法可以根據(jù)需要進行可視化調(diào)整,title 參數(shù)是一個字符串,而參數(shù) options 是一個對象,內(nèi)容如下:
{ "http://": "Visual Options", "body": "", "icon": " ", "image": " ", "badge": " ", "vibrate": " ", "sound": " ", "dir": " ", "http://": "Behavioural Options", "tag": " ", "data": " ", "requireInteraction": " ", "renotify": " ", "silent": " ", "http://": "Both Visual & Behavioural Options", "actions": " ", "http://": "Information Option. No visual affect.", "timestamp": " " }
可以了解更多的細節(jié),每個選項在這里做什么- https://developer.mozilla.org...
當(dāng)有緊急、重要和時間敏感的信息需要與用戶分享時,推送通知是吸引用戶注意力的好方法。
例如,我們在 SessionStack 計劃利用推送通知讓我們的用戶知道他們的產(chǎn)品何時出現(xiàn)崩潰、問題或異常。這將讓我們的用戶立即知道發(fā)生了什么錯誤。然后,他們可以將問題作為視頻回放,并利用我們的庫收集的數(shù)據(jù)(如DOM更改、用戶交互、網(wǎng)絡(luò)請求、未處理的異常和調(diào)試消息)查看發(fā)生在最終用戶身上的所有事情。
原文:
https://blog.sessionstack.com...
代碼部署后可能存在的BUG沒法實時知道,事后為了解決這些BUG,花了大量的時間進行l(wèi)og 調(diào)試,這邊順便給大家推薦一個好用的BUG監(jiān)控工具 Fundebug。
你的點贊是我持續(xù)分享好東西的動力,歡迎點贊!
交流干貨系列文章匯總?cè)缦?,覺得不錯點個Star,歡迎 加群 互相學(xué)習(xí)。
https://github.com/qq44924588...
我是小智,公眾號「大遷世界」作者,對前端技術(shù)保持學(xué)習(xí)愛好者。我會經(jīng)常分享自己所學(xué)所看的干貨,在進階的路上,共勉!
關(guān)注公眾號,后臺回復(fù)福利,即可看到福利,你懂的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/100796.html
摘要:推送通知這一功能在移動端已經(jīng)非常普遍。消息推送和通知消息推送和通知是兩個不同的接口。消息通知網(wǎng)絡(luò)應(yīng)用中的服務(wù)工作線程或者腳本進行操作向用戶顯示消息通知。是消息推送服務(wù)之一。可以從對象的屬性值獲得處理消息推送的請求地址。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScr...
摘要:數(shù)據(jù)作為消息通過傳輸,每個消息由一個或多個幀組成,其中包含正在發(fā)送的數(shù)據(jù)有效負載。幀數(shù)據(jù)如上所述,數(shù)據(jù)可以被分割成多個幀。但是,規(guī)范希望能夠處理交錯的控制幀。 文章底部分享給大家一套 react + socket 實戰(zhàn)教程 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第5篇。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯過了前面的章...
摘要:安裝事件綁定在文件中,當(dāng)安裝成功后,事件就會被觸發(fā)。激活當(dāng)安裝完成后并進入激活狀態(tài),會觸發(fā)事件。這會導(dǎo)致更新得不到響應(yīng)。由兩個構(gòu)成用來顯示系統(tǒng)的通知用來處理下發(fā)的消息這兩個都是建立在在基礎(chǔ)上的,在后臺響應(yīng)推送消息時間,并把他們傳遞給應(yīng)用。 showImg(https://segmentfault.com/img/bVbhbQf?w=1182&h=656); 原文地址: https://...
摘要:為了方便大家共同學(xué)習(xí),整理了之前博客系列的文章,目前已整理是如何工作這個系列,可以請猛戳博客查看。以下列出該系列目錄,歡迎點個星星,我將更友動力整理理優(yōu)質(zhì)的文章,一起學(xué)習(xí)。 為了方便大家共同學(xué)習(xí),整理了之前博客系列的文章,目前已整理 JavaScript 是如何工作這個系列,可以請猛戳GitHub博客查看。 以下列出該系列目錄,歡迎點個星星,我將更友動力整理理優(yōu)質(zhì)的文章,一起學(xué)習(xí)。 J...
閱讀 549·2021-08-31 09:45
閱讀 1660·2021-08-11 11:19
閱讀 895·2019-08-30 15:55
閱讀 833·2019-08-30 10:52
閱讀 2865·2019-08-29 13:11
閱讀 2937·2019-08-23 17:08
閱讀 2847·2019-08-23 15:11
閱讀 3077·2019-08-23 14:33