net::ERR_HTTP2_PROTOCOL_ERROR 是关于什么的?

新手上路,请多包涵

我目前正在开发一个网站,该网站在 Google Chrome 上触发 net::ERR_HTTP2_PROTOCOL_ERROR 200 错误。我不确定究竟是什么引发了这个错误,我只是注意到它只有在以 HTTPS 访问网站时才会弹出。我不能 100% 确定它是相关的,但看起来它会阻止 JavaScript 正确执行。

例如,发生以下情况:

  1. 我正在使用 HTTPS 访问网站

  2. 我通过 https://publish.twitter.com 集成的 Twitter 提要根本没有加载

  3. 我可以在控制台中注意到 ERR_HTTP2_PROTOCOL_ERROR

  4. 如果我删除加载 Twitter 提要的代码,错误仍然存在

  5. 如果我以 HTTP 访问该网站,则会出现 Twitter 提要并且错误消失

谷歌浏览器是唯一触发错误的网络浏览器:它在 Edge 和 Firefox 上运行良好。 (注意:我用 Safari 尝试过,我也有类似的 kcferrordomaincfnetwork 303 错误)

我想知道它是否与服务器返回的标头有关,因为错误中提到了“200”,并且 404 / 500 页面没有触发任何内容。

问题是根本没有记录错误。谷歌搜索给我的结果很少。此外,我注意到它出现在最近的 Google Chrome 版本中;该错误不会在 v.64.X 上弹出,但在 v.75+ 上会出现(无论操作系统如何;我正在使用 Mac tho)。


可能与 Firefox 上的网站正常有关,但与 Safari 上无关(kCFErrorDomainCFNetwork 错误 303)和 Chrome(net::ERR_SPDY_PROTOCOL_ERROR)


进一步调查的结果如下:

  • 如果服务器返回 404 而不是 2XX,则错误不会在完全相同的页面上弹出
  • 使用 HTTPS 证书不会在本地弹出错误
  • 在使用不同证书的不同服务器上弹出错误(两者都是 OVH)
  • 无论使用什么 PHP 版本,从 5.6 到 7.3,都会弹出错误(使用的框架:Cakephp 2.10)

根据要求,以下是失败资源的返回标头,即整个网页。即使在每个具有 HTTP 标头 200 的页面上触发错误,这些页面总是在客户端的浏览器上加载,但有时会丢失一个元素(在我的示例中,外部 Twitter 提要)。网络选项卡上的所有其他资产都有成功返回,但整个文档本身除外。 控制台中失败的行

Google Chrome 标头(有错误):

铬标头

Firefox 标头(无错误):

火狐标头

控制台中的 curl --head --http2 请求返回以下成功:

 HTTP/2 200
date: Fri, 04 Oct 2019 08:04:51 GMT
content-type: text/html; charset=UTF-8
content-length: 127089
set-cookie: SERVERID31396=2341116; path=/; max-age=900
server: Apache
x-powered-by: PHP/7.2
set-cookie: xxxxx=0919c5563fc87d601ab99e2f85d4217d; expires=Fri, 04-Oct-2019 12:04:51 GMT; Max-Age=14400; path=/; secure; HttpOnly
vary: Accept-Encoding


尝试使用 chrome://net-export/ 和 https://netlog-viewer.appspot.com 工具更深入地告诉我请求以 RST_STREAM 结尾:

 t=123354 [st=5170]    HTTP2_SESSION_RECV_RST_STREAM
                      --> error_code = "2 (INTERNAL_ERROR)"
                      --> stream_id = 1

对于我在 一篇文章中读到的内容,“ 在 HTTP/2 中,如果客户端想要中止请求,它会发送一个 RST_STREAM。当服务器接收到一个 RST_STREAM 时,它将停止向客户端发送 DATA 帧,从而停止响应(或下载)。该连接仍可用于其他请求,并且与已中止的请求/响应并发的请求/响应可能会继续进行。[…] 有可能当 RST_STREAM 从客户端到服务端,请求的全部内容在传输中,会到达客户端,客户端会丢弃,但是对于大的响应内容,发送一个RST_STREAM可能有很好的机会在整个请求之前到达服务端响应内容被发送,因此将节省带宽。

所描述的行为与我可以观察到的行为相同。但这意味着浏览器是罪魁祸首,然后我不明白为什么它会发生在两个相同的页面上,一个具有 200 标题,另一个具有 404(如果我禁用 JS,也是如此)。

原文由 Tristan G 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.4k
2 个回答

我没有弄清楚到底发生了什么,但我找到了解决方案。

OVH 的 CDN 功能 是罪魁祸首。我将它安装在我的主机服务上,但因为我不需要它而对我的域禁用。

不知何故,当我启用它时,一切正常。

我认为它迫使 Apache 使用 HTTP2 协议,但我不明白的是,我的每个标题中确实提到了 HTTP2,我认为这意味着服务器正在使用正确的协议进行响应。

因此,针对我的特殊情况的解决方案是在所有相关域上启用 CDN 选项。

如果有人更好地理解这里可能发生的事情,请随时分享解释。

原文由 Tristan G 发布,翻译遵循 CC BY-SA 4.0 许可协议

就我而言(HTTPS 协议,PHP),原因是:

错误的 404 标头(

 header('404 Not found', true);

代替

header($_SERVER['SERVER_PROTOCOL'].' 404 Not found', true);

) - 来自以前的 Web 开发人员的遗产。

原文由 Andrews32 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题