原文地址:FAQhtml
譯文地址:FAQ前端
譯者:劉鵬android
這個問題很有爭議,主要是由於有一些場景使得這個問題比較難以追因和理解。github
讓咱們先從 Android 開始。Android 系統被設計成監聽推送消息,一旦收到一條消息,就會喚醒對應的 Android 應用來處理推送消息,而無論這個應用是否關閉。web
Android 上的任何瀏覽器和上述應用的表現是一致的,當接收到一條推送消息的時候,瀏覽器會被喚醒,而後瀏覽器再喚醒你的 service worker,發出推送事件。chrome
桌面操做系統則有細微差異。其中 Mac OS X 系統是最容易理解的,由於有一個可視化的標記來輔助解釋不一樣的場景。api
在 Mac OS X 系統上,你能夠從 dock (列表中)的應用 icon 下方的標記來判斷一個程序是否在運行。瀏覽器
若是你對比一下下面 dock 中的兩個 Chrome icon,經過 icon 下面的標記咱們能夠知道左邊的那個正在運行,然而右邊的那個 Chrome 沒有在運行,由於缺乏了下面的標記。bash
在桌面系統上接收推送消息的狀況下,當瀏覽器在運行的時候(即在 icon 下面有一個標記),你能夠接收到消息。
這意味着即便瀏覽器窗口沒有打開,你仍然能夠在你的 service worker 當中接收到推送消息,由於瀏覽器正在後臺運行。
推送不能接收到的惟一狀況就是瀏覽器被徹底關閉了,即徹底不在運行( icon 下沒有標記)。這一樣適用於 Windows 操做系統,雖然在 Windows 上判斷 Chrome 是否在後臺運行有一點複雜。
在 Android 系統的 Chrome 瀏覽器上,Web App 能夠被添加到桌面。當它在桌面被打開的時候,能夠在沒有地址欄的全屏模式打開,就像下面顯示的那樣。
爲了保持體驗的一致性,開發者也想用戶在點擊通知以後可以全屏打開他們的 Web App。
Chrome 在某種程度上實現了這個特性,雖然你可能發現它不太靠譜而且難以追因。相關的實現細節以下:
在 Android 系統上,添加到桌面的網站在點擊推送消息的時候,應該被容許以 standalone(獨立) 模式打開。然而即便網站被添加到了桌面,因爲 Chromium 依然不能檢測到這些網站是否在桌面上。咱們啓發式地採用了下面這種方法:那些在最近 10 天內從桌面啓動過的網站,點擊通知後將以 standalone 模式打開。-- Chrome Issue
這就意味着,除非你的用戶足夠頻繁地經過桌面訪問你的站點,不然的話你的通知只會打開一個普通的瀏覽器 UI。
這個問題將進一步解決。
注意: 這個只是 Chrome 的表現,其它瀏覽器也會有一些不一樣。若是你有任何須要討論的,請儘管提出 issue。
即便瀏覽器窗口是關閉的,service worker 依然能夠工做。而 web socket 只有在瀏覽器和網頁保持打開的狀態下才能正常工做。
這個問題有不少方面,最簡單的解釋方法是逐步介紹 Web 推送和 Chrome 的歷史。(別擔憂,很短)
當 Chrome 首次實現 Web 推送時,是使用 Google Cloud Messaging(GCM)來支持從服務器向瀏覽器發送推送消息的。
但這不是 Web 推送。早期的 Chrome 和 GCM 並非「真正的」 Web 推送有如下幾個緣由:
7月,Web 推送中的一項新功能發佈 - Application Server Keys(即規範中的 VAPID )。Chrome 在支持此新 API 時,棄用了 GCM,改用 Firebase Cloud Messaging(FCM)做爲消息傳遞服務。這很重要,緣由以下:
如今已經存在的關於 Web 推送的內容中存在大量混淆,其中大部份內容都引用了 GCM 或 FCM。 若是內容用了 GCM,你能夠將其視爲是過期內容的標誌,或者它太過針對於 Chrome。(我在一些舊的文章中也犯了這個錯誤)
所以,你應該將 Web 推送視爲瀏覽器的一部分,瀏覽器使用推送服務來管理髮送和接收消息,其中推送服務將接受符合「Web 推送協議」的請求。若是按照這樣進行思考,你就能夠無視瀏覽器及其使用的推送服務的干擾,並直接開始工做了。
本書的編寫專一於 Web 推送的標準方法,因此有意忽略其餘任何內容。
對於那些已經發現 Firebase Web SDK 且注意到它有 JavaScript 版本的消息傳遞 API 的人,可能會想知道它與 Web 推送的區別。
消息傳遞 SDK(Firebase Cloud Messaging JS SDK)在幕後作了一些工做以便更輕鬆地實現 Web 推送。
PushSubscription
及其各個字段。其實它在底層使用的仍是 Web 推送,可是目的就是把 Web 推送抽象出來。
就像我在上一個問題中所說的那樣,若是將 Web 推送視爲瀏覽器加上推送服務,那麼你能夠將 Firebase 中 的 Messaging SDK 視爲一個簡化的 Web 推送的庫。
譯文地址:Web 推送:常見問題以及錯誤反饋
譯者:劉文濤
當你使用網絡推送遇到問題時,可能很難去調試這個問題或尋求幫助。 本文將概述一些常見問題以及若是你在 Chrome 或 Firefox 中發現錯誤,應該怎麼去作。
在咱們深刻調試推送以前,你可能遇到 service workers 自己的問題,文件未更新,未註冊或通常的異常行爲。 關於調試 service workers 的文檔很是完善,若是你是初次使用 service worker 開發的話 ,我強烈建議你去閱讀一下。
在開發和測試 Web 推送的兩個階段中,每一個階段都遇到獨有的一些常見問題。
若是沒法發送和接收推送消息,而且本文檔中的相關部分不能幫助你調試問題,那麼你可能發現了推送機制自己的一個 Bug。在這種狀況下,請參閱 「如何提交錯誤報告」部分,提交一份包含全部重要信息的錯誤報告,以加快錯誤修復過程。
在提交錯誤報告以前我想說的一件事是:Firefox 和 Mozilla 自動推送服務給了不少有用的錯誤信息。 若是你遇到問題而且不肯定是什麼問題的時候,那麼請在 Firefox 中進行測試,看看是否能夠收到了更有用的錯誤消息。
受權問題是開發人員在開始使用 Web 推送時遇到的最多見問題之一。 這一般是配置站點應用服務器密鑰(又名 VAPID 密鑰)的問題。
在 Firefox 和 Chrome 中,支持推送的最簡單方法是在 subscribe()
調用中提供 applicationServerKey
。這樣作很差的是,前端和服務器密鑰之間的任何差別都會致使受權錯誤。
對於使用 FCM 做爲推送服務的 Chrome,你將收到來自 FCM:關於UnauthorizedRegistration
response【未經受權註冊】 的一系列不一樣的錯誤,全部錯誤都涉及應用程序服務器密鑰。
在如下任何一種狀況下,你都會收到一個 UnauthorizedRegistration
錯誤:
Authorization
header。完整的錯誤響應以下所示:
<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 和 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"
}
複製代碼
有一系列的問題可能致使推送服務返回非 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 控制檯中看到一條錯誤消息,以下所示:
要檢查 Chrome 中是否存在此問題,請執行如下操做:
若是有效負載的解密存在問題,將看到相似於上面顯示的錯誤。 (請注意詳細信息列中的 AES-GCM decryption failed
消息。)
若是是這個問題,有一些工具能夠幫助你調試加密:
若是你沒有在 service worker 中收到推送事件,而且沒有看到任何解密錯誤,多是瀏覽器沒法鏈接到推送服務。
在 Chrome 中,能夠經過頁面:chrome://gcm-internals
中的「接收消息日誌」模塊來檢查瀏覽器是否正在接收消息。
若是沒有及時看到消息,請確保你的瀏覽器的鏈接狀態爲 CONNECTED
,以下圖所示:
若是連接狀態不是 「CONNECTED」,可能須要刪除當前的配置文件並建立一個新的。 若是仍然沒法解決問題,請按照下面章節的建議提出錯誤報告。
若是上面的方式都不能解決你的問題,而且沒有跡象代表問題多是什麼,請根據你遇到問題的瀏覽器提出問題:
對於 Chrome,你能夠在此處反饋問題:bugs.chromium.org/p/chromium/…
對於 Firefox,你能夠在此處反饋問題: bugzilla.mozilla.org/
如何提供一個好的的錯誤報告,你應該作到如下幾點:
若是你能提供一個可重現的例子,或者源代碼或託管網站,它常常可讓咱們更快速地診斷和解決問題。