原文地址: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/
如何提供一个好的的错误报告,你应该作到如下几点:
若是你能提供一个可重现的例子,或者源代码或托管网站,它常常可让咱们更快速地诊断和解决问题。