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

相关文章
相关标签/搜索