《Web 推送通知》系列翻譯 | 第十一篇:FAQ && 第十二篇:常見問題以及錯誤反饋

第十一篇:FAQ

原文地址:FAQhtml

譯文地址:FAQ前端

譯者:劉鵬android

校對者:楊芯芯任家樂git

爲何推送在瀏覽器關閉的時候不工做

這個問題很有爭議,主要是由於有一些場景使得這個問題比較難以追因和理解。github

讓咱們先從 Android 開始。Android 系統被設計成監聽推送消息,一旦收到一條消息,就會喚醒對應的 Android 應用來處理推送消息,而無論這個應用是否關閉。web

Android 上的任何瀏覽器和上述應用的表現是一致的,當接收到一條推送消息的時候,瀏覽器會被喚醒,而後瀏覽器再喚醒你的 service worker,發出推送事件。chrome

桌面操做系統則有細微差異。其中 Mac OS X 系統是最容易理解的,由於有一個可視化的標記來輔助解釋不一樣的場景。api

在 Mac OS X 系統上,你能夠從 dock (列表中)的應用 icon 下方的標記來判斷一個程序是否在運行。瀏覽器

若是你對比一下下面 dock 中的兩個 Chrome icon,經過 icon 下面的標記咱們能夠知道左邊的那個正在運行,然而右邊的那個 Chrome 沒有在運行,由於缺乏了下面的標記。bash

OS X 的示例

在桌面系統上接收推送消息的狀況下,當瀏覽器在運行的時候(即在 icon 下面有一個標記),你能夠接收到消息。

這意味着即便瀏覽器窗口沒有打開,你仍然能夠在你的 service worker 當中接收到推送消息,由於瀏覽器正在後臺運行。

推送不能接收到的惟一狀況就是瀏覽器被徹底關閉了,即徹底不在運行( icon 下沒有標記)。這一樣適用於 Windows 操做系統,雖然在 Windows 上判斷 Chrome 是否在後臺運行有一點複雜。

我如何讓用戶在點擊推送消息後,可以全屏打開我添加到桌面的 Web App?

在 Android 系統的 Chrome 瀏覽器上,Web App 能夠被添加到桌面。當它在桌面被打開的時候,能夠在沒有地址欄的全屏模式打開,就像下面顯示的那樣。

桌面圖標全屏方式打開

爲了保持體驗的一致性,開發者也想用戶在點擊通知以後可以全屏打開他們的 Web App。

Chrome 在某種程度上實現了這個特性,雖然你可能發現它不太靠譜而且難以追因。相關的實現細節以下:

在 Android 系統上,添加到桌面的網站在點擊推送消息的時候,應該被容許以 standalone(獨立) 模式打開。然而即便網站被添加到了桌面,因爲 Chromium 依然不能檢測到這些網站是否在桌面上。咱們啓發式地採用了下面這種方法:那些在最近 10 天內從桌面啓動過的網站,點擊通知後將以 standalone 模式打開。-- Chrome Issue

這就意味着,除非你的用戶足夠頻繁地經過桌面訪問你的站點,不然的話你的通知只會打開一個普通的瀏覽器 UI。

這個問題將進一步解決。

注意: 這個只是 Chrome 的表現,其它瀏覽器也會有一些不一樣。若是你有任何須要討論的,請儘管提出 issue

爲何這個比 web sockets 要好?

即便瀏覽器窗口是關閉的,service worker 依然能夠工做。而 web socket 只有在瀏覽器和網頁保持打開的狀態下才能正常工做。

GCM、 FCM、 Web 推送 和 Chrome 是怎麼回事?

這個問題有不少方面,最簡單的解釋方法是逐步介紹 Web 推送和 Chrome 的歷史。(別擔憂,很短)

2014 年 12 月

當 Chrome 首次實現 Web 推送時,是使用 Google Cloud Messaging(GCM)來支持從服務器向瀏覽器發送推送消息的。

但這不是 Web 推送。早期的 Chrome 和 GCM 並非「真正的」 Web 推送有如下幾個緣由:

  • GCM 要求開發人員在 Google Developers Console 上註冊賬戶。
  • Chrome 和 GCM 須要一個特殊的由 Web 應用程序共享的發送者 ID,來正確地設置消息。
  • GCM 的服務器接收的是自定義的 API 請求,而非 Web 標準。
2016 年 7 月

7月,Web 推送中的一項新功能發佈 - Application Server Keys(即規範中的 VAPID )。Chrome 在支持此新 API 時,棄用了 GCM,改用 Firebase Cloud Messaging(FCM)做爲消息傳遞服務。這很重要,緣由以下:

  • Chrome 和 Application Server Keys 不須要使用 Google 或 Firebase 設置任何類型的項目,就能夠正常工做。
  • FCM 支持 Web 推送協議,這是全部 Web 推送服務都支持的 API。這意味着不管瀏覽器使用什麼推送服務,你只需發送相同類型的請求,它就會推送消息。
爲何如今使人困惑?

如今已經存在的關於 Web 推送的內容中存在大量混淆,其中大部份內容都引用了 GCM 或 FCM。 若是內容用了 GCM,你能夠將其視爲是過期內容的標誌,或者它太過針對於 Chrome。(我在一些舊的文章中也犯了這個錯誤)

所以,你應該將 Web 推送視爲瀏覽器的一部分,瀏覽器使用推送服務來管理髮送和接收消息,其中推送服務將接受符合「Web 推送協議」的請求。若是按照這樣進行思考,你就能夠無視瀏覽器及其使用的推送服務的干擾,並直接開始工做了。

本書的編寫專一於 Web 推送的標準方法,因此有意忽略其餘任何內容。

Firebase 有一個 JavaScript SDK,它是什麼以及爲何會存在?

對於那些已經發現 Firebase Web SDK 且注意到它有 JavaScript 版本的消息傳遞 API 的人,可能會想知道它與 Web 推送的區別。

消息傳遞 SDK(Firebase Cloud Messaging JS SDK)在幕後作了一些工做以便更輕鬆地實現 Web 推送。

  • 只須要關心 FCM 令牌(僅僅是一個字符串),而沒必要關心 PushSubscription 及其各個字段。
  • 經過使用每一個用戶的令牌,你可使用專有的 FCM API 來觸發推送消息。此 API 不須要加密有效負載,能夠在 POST 請求 body 中發送普通(未加密)的文本有效載荷。
  • FCM 的專有 API 支持自定義功能,例如 FCM 主題(儘管相關文檔不多,但它也能夠在 Web 上運行)。
  • 最後,FCM 支持 Android、iOS 和 Web,所以對於一些團隊來講,在現有項目中更容易使用。

其實它在底層使用的仍是 Web 推送,可是目的就是把 Web 推送抽象出來。

就像我在上一個問題中所說的那樣,若是將 Web 推送視爲瀏覽器加上推送服務,那麼你能夠將 Firebase 中 的 Messaging SDK 視爲一個簡化的 Web 推送的庫。

第十一篇:Web 推送:常見問題以及錯誤反饋

原文地址:common issues and reporting bugs

譯文地址:Web 推送:常見問題以及錯誤反饋

譯者:劉文濤

校對者:張卓 劉鵬

當你使用網絡推送遇到問題時,可能很難去調試這個問題或尋求幫助。 本文將概述一些常見問題以及若是你在 Chrome 或 Firefox 中發現錯誤,應該怎麼去作。

在咱們深刻調試推送以前,你可能遇到 service workers 自己的問題,文件未更新,未註冊或通常的異常行爲。 關於調試 service workers 的文檔很是完善,若是你是初次使用 service worker 開發的話 ,我強烈建議你去閱讀一下。

在開發和測試 Web 推送的兩個階段中,每一個階段都遇到獨有的一些常見問題。

  • 發送消息: 首先應確保發送消息成功。正確返回的 HTTP 狀態碼應該是 201。 若是不是:
    • 檢查受權錯誤: 若是收到受權錯誤消息,請參閱下面 「受權相關問題部分"。
    • 其餘API錯誤: 若是收到非201狀態代碼,請參閱下面的「HTTP 狀態代碼部分「以獲取有關問題緣由的指導。
  • 接收消息: 若是你可以成功發送消息,但在瀏覽器上未收到消息:
    • 檢查加密問題: 請參閱下面的「有效負載加密問題部分「。
    • 檢查鏈接問題: 若是是在 Chrome 上出的問題,可能與鏈接有關。 可參閱下面的「鏈接問題」部分。

若是沒法發送和接收推送消息,而且本文檔中的相關部分不能幫助你調試問題,那麼你可能發現了推送機制自己的一個 Bug。在這種狀況下,請參閱 「如何提交錯誤報告」部分,提交一份包含全部重要信息的錯誤報告,以加快錯誤修復過程。

在提交錯誤報告以前我想說的一件事是:Firefox 和 Mozilla 自動推送服務給了不少有用的錯誤信息。 若是你遇到問題而且不肯定是什麼問題的時候,那麼請在 Firefox 中進行測試,看看是否能夠收到了更有用的錯誤消息。

受權問題

受權問題是開發人員在開始使用 Web 推送時遇到的最多見問題之一。 這一般是配置站點應用服務器密鑰(又名 VAPID 密鑰)的問題。

在 Firefox 和 Chrome 中,支持推送的最簡單方法是在 subscribe() 調用中提供 applicationServerKey。這樣作很差的是,前端和服務器密鑰之間的任何差別都會致使受權錯誤。

在 Chrome + 雲消息傳遞FCM

對於使用 FCM 做爲推送服務的 Chrome,你將收到來自 FCM:關於UnauthorizedRegistration response【未經受權註冊】 的一系列不一樣的錯誤,全部錯誤都涉及應用程序服務器密鑰。

在如下任何一種狀況下,你都會收到一個 UnauthorizedRegistration 錯誤:

  • 沒有在 FCM 的請求中定義 Authorization header。
  • 用於訂閱用戶的應用程序密鑰與用於簽署 Authorization header 的密鑰不匹配。
  • 你的 JWT【Json web token】到期無效,即超過 24 小時或 JWT 已過時。
  • JWT 異常或值無效。

完整的錯誤響應以下所示:

<HTML>\n<HEAD>\n<TITLE>UnauthorizedRegistration</TITLE>\n</HEAD>\n<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n<H1>UnauthorizedRegistration</H1>\n<H2>Error 400</H2>\n</BODY>\n</HTML>\n
複製代碼

若是你在 Chrome 中收到此錯誤消息,能夠考慮在 Firefox 中進行測試,看看它是否可以提供有關此問題的更多信息。

Firefox and Mozilla 自動推送

Firefox 和 Mozilla 自動推送 爲 Authorization 受權問題提供了一系列很是友好的錯誤提示。

若是你的推送請求中未包含 Authorization header,你將會收到來自 Mozilla 自動推送的 Unauthorized 未受權的錯誤信息。

{  
	"errno": 109,  
	"message": "Request did not validate missing authorization header",  
	"code": 401,  
	"more_info": "http://autopush.readthedocs.io/en/latest/http.html\#error-codes",  
	"error": "Unauthorized"  
}
複製代碼

若是 JWT 的已過時,你將會收到一條 Unauthorized 未受權的錯誤信息,該信息說明該令牌已過時。

{  
	"code": 401,  
	"errno": 109,  
	"error": "Unauthorized",  
	"more_info": "http://autopush.readthedocs.io/en/latest/http.html\#error-codes",  
	"message": "Request did not validate Invalid bearer token: Auth expired"  
}
複製代碼

若是用戶訂閱時的應用服務器密鑰和受權 header 頭簽名時的應用服務器密鑰不一樣,則會返回未找到錯誤

{  
	"errno": 102,  
	"message": "Request did not validate invalid token",  
	"code": 404,  
	"more_info": "http://autopush.readthedocs.io/en/latest/http.html\#error-codes",  
	"error": "Not Found"  
}
複製代碼

最後,若是你的的 JWT 中有無效值(例如,「alg」 值是一個異常的值),你將會從 Mozilla 自動推送中收到如下錯誤信息:

{  
	"code": 401,  
	"errno": 109,  
	"error": "Unauthorized",  
	"more_info": "http://autopush.readthedocs.io/en/latest/http.html\#error-codes",  
	"message": "Request did not validate Invalid Authorization Header"  
}
複製代碼

HTTP 狀態碼

有一系列的問題可能致使推送服務返回非 201 響應代碼。 下面是相關 HTTP 狀態碼列表及其與 Web 推送相關的問題描述。

Status Code Description
429 請求太多。 應用程序服務器推送服務達到了速率限制。 推送服務的響應當中應該包括了 「Retry-After" 標頭,來指示你須要等待多久來發送另外一個請求。
400 無效的請求。 你的某一個 Header 無效或格式不正確。
404 沒有找到。訂閱已過時。在這種狀況下,你應該從你的後臺刪除 PushSubscription,而且等待一個時機再次給用戶訂閱。
410 失效. 訂閱再也不有效,應該從你的後臺移除。這能夠在 `PushSubscription` 上經過調用 `unsubscribe()` 方法來移除。
413 有效載荷大小太大。 推送服務必須支持的最小大小有效負載是 4096 字節(或4kb)。 任何更大的大小均可能致使此錯誤。

若是 http 狀態碼不在此列表中且錯誤信息沒有給到幫助,能夠查看 Web Push Protocol spec (Web 推送協議),看下這個狀態碼是在哪些場景下觸發。

有效負載加密問題

若是成功觸發推送消息(即向 Web 推送服務發送消息並接收到 201 響應碼),但推送事件沒有在 service worker 中觸發,這一般表示瀏覽器沒法解密其接收到的消息。

若是是這種狀況,能夠在 Firefox 的 DevTools 控制檯中看到一條錯誤消息,以下所示:

Firefox DevTools with decryption message

要檢查 Chrome 中是否存在此問題,請執行如下操做:

  1. 地址欄輸入 chrome://gcm-internals ,進入並點擊「Start Recording【開始錄製】」按鈕。
Chrome GCM internals record
  1. 觸發一個推送消息,看下「消息解密失敗日誌」。
GCM internals decryption log

若是有效負載的解密存在問題,將看到相似於上面顯示的錯誤。 (請注意詳細信息列中的 AES-GCM decryption failed 消息。)

若是是這個問題,有一些工具能夠幫助你調試加密:

鏈接問題

若是你沒有在 service worker 中收到推送事件,而且沒有看到任何解密錯誤,多是瀏覽器沒法鏈接到推送服務。

在 Chrome 中,能夠經過頁面:chrome://gcm-internals 中的「接收消息日誌」模塊來檢查瀏覽器是否正在接收消息。

GCM internals receive message log

若是沒有及時看到消息,請確保你的瀏覽器的鏈接狀態爲 CONNECTED,以下圖所示:

GCM internals connection state

若是連接狀態不是 「CONNECTED」,可能須要刪除當前的配置文件並建立一個新的。 若是仍然沒法解決問題,請按照下面章節的建議提出錯誤報告。

錯誤反饋

若是上面的方式都不能解決你的問題,而且沒有跡象代表問題多是什麼,請根據你遇到問題的瀏覽器提出問題:

對於 Chrome,你能夠在此處反饋問題:bugs.chromium.org/p/chromium/…

對於 Firefox,你能夠在此處反饋問題: bugzilla.mozilla.org/

如何提供一個好的的錯誤報告,你應該作到如下幾點:

  • 你測試的瀏覽器版本(例如 Chrome 版本50,Chrome 版本51,Firefox 版本50,Firefox 版本51)。
  • 給出一個例子,能夠重現這個問題;
  • 報告中應該包括請求的全部信息(即對推送服務的網絡請求的內容[包含 header])。
  • 報告中應該包括網絡請求的返回的響應數據。

若是你能提供一個可重現的例子,或者源代碼或託管網站,它常常可讓咱們更快速地診斷和解決問題。

更多分享,請關注YFE:

上一篇:《Web 推送通知》系列翻譯 | 第九篇:通知行爲 && 第十篇:經常使用的通知模式

相關文章
相關標籤/搜索