当您遇到 Web Push 问题时,可能很难调试问题或寻求帮助。本文档简要介绍了一些常见问题,以及在 Chrome 或 Firefox 中发现 bug 时应采取的措施。
在深入了解如何调试推送之前,您可能会遇到调试 Service Worker 本身、文件无法更新、注册失败或通常只是异常行为的问题。如果您刚刚开始接触 Service Worker 开发,强烈建议您参阅有关调试 Service Worker 的绝佳文档。
在开发和测试网站推送时,有两个不同的阶段需要检查,每个阶段都有自己的一组常见问题:
- 发送消息:确保发送消息成功。您应该会收到 HTTP 代码 201。如果您不是:
- 检查是否存在授权错误:如果您收到授权错误消息,请参阅“授权问题”部分。
- 其他 API 错误:如果您收到的响应状态代码不是 201,请参阅 “HTTP 状态代码”部分,了解问题原因。
- 接收消息:如果您能够成功发送消息,但浏览器上未收到消息,请执行以下操作:
- 检查加密问题:请参阅“载荷加密问题”部分。
- 检查连接问题:如果问题出在 Chrome 上,可能是连接问题。如需了解详情,请参阅“连接问题”部分。
如果您无法发送和接收推送消息,并且本文档中的相关部分无法帮助您调试问题,则可能是因为推送机制本身存在 bug。在这种情况下,请参阅提交 bug 报告部分,提交包含所有必要信息的完整 bug 报告,以加快 bug 修复流程。
在开始之前,我想提醒一点,Firefox 和 Mozilla AutoPush 服务会显示非常详细的错误消息。如果您遇到问题,并且不确定问题出在哪里,请在 Firefox 中进行测试,看看能否收到更有帮助的错误消息。
授权问题
授权问题是开发者在开始使用 Web Push 时最常遇到的问题之一。这通常是网站的应用服务器密钥(也称为 VAPID 密钥) 配置方面的问题。
若要在 Firefox 和 Chrome 中同时支持推送,最简单的方法是在 subscribe()
调用中提供 applicationServerKey
。缺点是,如果前端和服务器的密钥之间存在任何差异,都会导致授权错误。
在 Chrome 和 FCM 上
对于使用 FCM 作为推送服务的 Chrome,如果发生各种不同的错误(所有这些错误都涉及应用服务器密钥),您会收到 FCM 发送的 UnauthorizedRegistration
响应。
在以下任一情况下,您都会收到 UnauthorizedRegistration
错误:
- 如果您未在向 FCM 发送的请求中定义
Authorization
标头。 - 用于订阅用户的应用密钥与用于对 Authorization 标头进行签名的密钥不匹配。
- JWT 中的到期时间无效,即到期时间超过 24 小时或 JWT 已过期。
- JWT 格式错误或包含无效值。
完整的错误响应如下所示:
<html>
<head>
<title>UnauthorizedRegistration</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1>UnauthorizedRegistration</h1>
<h2>Error 400</h2>
</body>
</html>
如果您在 Chrome 中收到此错误消息,不妨考虑在 Firefox 中进行测试,看看能否获得更多问题信息。
Firefox 和 Mozilla AutoPush
Firefox 和 Mozilla AutoPush 针对 Authorization
问题提供了一组友好的错误消息。
如果您的推送请求中未包含 Authorization
标头,您还会收到 Mozilla AutoPush 的 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"
}
如果用户订阅时与签署授权标头时应用服务器密钥不同,系统会返回 Not Found
错误:
{
"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 AutoPush 发送的以下错误:
{
"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 推送方面的含义。
状态代码 | 说明 |
---|---|
429 | 请求数量过多。您的应用服务器已达到推送服务的速率限制。服务的响应应包含“Retry-After”标头,以指明需要等待多长时间才能发出另一个请求。 |
400 | 请求无效。您的某个标题无效或格式不正确。 |
404 | 未找到。在这种情况下,您应从后端删除 PushSubscription,并等待机会重新订阅用户。 |
410 | 已消失。该订阅已失效,应从您的后端中移除。您可以通过对 `PushSubscription` 调用 `unsubscribe()` 来重现此问题。 |
413 | 载荷大小过大。推送服务必须支持的载荷最小大小为 4096 字节(或 4kb)。任何更大的值都可能会导致此错误。 |
如果 HTTP 状态代码不在此列表中,并且错误消息没有帮助,请查看 Web Push 协议规范,看看该状态代码是否被提及,以及该状态代码的适用场景。
载荷加密问题
如果您可以成功触发推送消息(即向 Web 推送服务发送消息并收到 201 响应代码),但推送事件从未在您的服务工作器中触发,这通常表示浏览器未能解密收到的消息。
如果是这种情况,您应该会在 Firefox 的开发者工具控制台中看到如下错误消息:
如需检查 Chrome 是否存在此问题,请执行以下操作:
- 前往 about://gcm-internals,然后点击“开始录制”按钮。
- 触发推送消息,然后查看“消息解密失败日志”。
如果载荷解密出现问题,您会看到类似于上面显示的错误。(请注意“详细信息”列中的 AES-GCM decryption failed
消息。)
如果您遇到的是加密问题,以下几个工具可能有助于调试加密:
连接问题
如果您在服务工作线程中未收到推送事件,并且未看到任何解密错误,则表示浏览器可能无法连接到推送服务。
在 Chrome 中,您可以通过检查 about://gcm-internals
中的“Receive Message Log”(收到消息日志)来检查浏览器是否正在接收消息。
如果您没有及时收到消息,请确保浏览器的连接状态为 CONNECTED
:
如果不是“已关联”,您可能需要删除当前付款资料,然后创建新的付款资料。如果这样做仍无法解决问题,请按照以下建议提交 bug 报告。
提交 bug 报告
如果上述所有方法都无法解决您的问题,并且您也找不到可能导致问题的原因,请针对出现问题的浏览器提出问题:
对于 Chrome,您可以在此处提出问题:https://bugs.chromium.org/p/chromium/issues/list 对于 Firefox,您应在此处提出问题:https://bugzilla.mozilla.org/
为了提供良好的 bug 报告,您应提供以下详细信息:
- 您测试时使用的浏览器(例如 Chrome 版本 50、Chrome 版本 51、Firefox 版本 50、Firefox 版本 51)。
- 演示问题的
PushSubscription
示例。 - 请附上任何示例请求(即向推送服务发出的网络请求的内容,包括标头)。
- 同时附上网络请求的任何示例响应。
如果您能提供可重现的问题示例(源代码或托管的网站),通常有助于加快诊断和解决问题。
下一步做什么
- 网络推送通知概览
- 推送通知的运作方式
- 为用户订阅
- 权限用户体验
- 使用 Web 推送库发送消息
- Web 推送协议
- 处理推送事件
- 显示通知
- 通知行为
- 常见通知模式
- 推送通知常见问题解答
- 常见问题和报告 bug