《Web 推送通知》系列翻译 | 第十一篇:FAQ && 第十二篇:常见问题以及错误反馈

第十一篇:FAQ

原文地址:FAQ

译文地址:FAQ

译者:刘鹏

校对者:杨芯芯任家乐

为什么推送在浏览器关闭的时候不工作

这个问题颇有争议,主要是因为有一些场景使得这个问题比较难以追因和理解。

让我们先从 Android 开始。Android 系统被设计成监听推送消息,一旦收到一条消息,就会唤醒对应的 Android 应用来处理推送消息,而不管这个应用是否关闭。

Android 上的任何浏览器和上述应用的表现是一致的,当接收到一条推送消息的时候,浏览器会被唤醒,然后浏览器再唤醒你的 service worker,发出推送事件。

桌面操作系统则有细微差别。其中 Mac OS X 系统是最容易理解的,因为有一个可视化的标记来辅助解释不同的场景。

在 Mac OS X 系统上,你可以从 dock (列表中)的应用 icon 下方的标记来判断一个程序是否在运行。

如果你对比一下下面 dock 中的两个 Chrome icon,通过 icon 下面的标记我们可以知道左边的那个正在运行,然而右边的那个 Chrome 没有在运行,因为缺少了下面的标记。

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 推送通知》系列翻译 | 第九篇:通知行为 && 第十篇:常用的通知模式

猜你喜欢

转载自juejin.im/post/5b8fa6ea6fb9a05ce37acfc9