什么是网络::: ERR_HTTP2_PROTOCOL_ERROR?

Tri*_*n G 12 https google-chrome http2

我目前正在网站上,该网站net::ERR_HTTP2_PROTOCOL_ERROR 200在Google Chrome浏览器上触发错误。我不确定究竟是什么会引起此错误,我只是注意到它仅在使用HTTPS访问网站时弹出。我不能100%确定是否相关,但是它似乎阻止了javascript的正确执行。

例如,发生以下情况:

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

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

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

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

  5. 如果我通过HTTP访问网站,则会显示Twitter feed,并且错误消失

谷歌浏览器是唯一会触发该错误的网络浏览器:它在Edge和Firefox上均可正常运行。(注:我尝试使用Safari,但出现类似kcferrordomaincfnetwork 303错误)

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

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

任何调查的线索将不胜感激!

提前致谢。

特里斯坦


编辑1:可能与Firefox上的“网站确定 ”相关,但与Safari上的“网站正常 ”无关(kCFErrorDomainCFNetwork错误303),也与Chrome无关(net :: ERR_SPDY_PROTOCOL_ERROR)


编辑2:进一步调查的结果如下:

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

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

Google Chrome标头(错误):

Chrome标题

Firefox标头(无错误):

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
Run Code Online (Sandbox Code Playgroud)

编辑4:尝试深入使用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
Run Code Online (Sandbox Code Playgroud)

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

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

use*_*495 49

对我来说,修复方法是将minBytesPerSecondIIS 设置为0. system.applicationHost/webLimits此设置可以在IIS 的配置编辑器中找到。默认情况下它设置为240。

在此输入图像描述

事实证明,如果服务器到客户端的数据吞吐量低于特定限制,某些网络服务器将切断与客户端的连接。这是为了防止“慢滴”拒绝服务攻击。但是,当无辜用户同时请求许多资源(例如单个页面上有大量图像)时,也可能会触发此限制,并且服务器被迫为每个请求分配过多的带宽,从而导致或更多请求低于吞吐量限制,这会导致服务器切断连接并net::ERR_HTTP2_PROTOCOL_ERROR在 Chrome 中显示。

例如,假设您一次请求 10 个 GIF 图像,每个 GIF 为 10 MB(总共 100 MB)。如果您从服务器的下载速度为每秒 1MB,您的浏览器将必须以某种方式将该 1MBps 分配给 10 张图像。现在,这里变得有趣了,因为带宽的分配方式似乎是随机的:

  1. 您的浏览器可能会在图像之间平均分配带宽,从而为每个图像分配 0.1MBps。所有下载速度均低于minBytesPerSecond240 字节的默认 IIS 限制,因此所有 GIF 下载均成功。
  2. 您的浏览器可能会优先考虑以 0.2MBps 传输前 5 个数据,并将后 5 个数据以 0MBps 的速度“暂停”,以便在前 5 个数据传输之后下载。但是,由于 0MBps 低于默认 IIS 限制minBytesPerSecond240 字节,因此服务器会切断连接到剩余的下载。

我能够通过以下步骤阻止连接被切断:

  1. 我使用 Chrome 的网络日志导出工具来chrome://net-export/查看ERR_HTTP2_PROTOCOL_ERROR错误背后的具体原因。我启动了日志,重现了错误,然后停止了日志。
  2. 我将日志导入https://netlog-viewer.appspot.com/#import的日志查看器中,并看到一个标题为 的有趣事件HTTP2_SESSION_RECV_RST_STREAM,其中包含错误代码8 (CANCEL)。

在此输入图像描述

  1. 我对术语“RST_STREAM”(这似乎是“重置流”的缩写形式)进行了一些谷歌搜索,并发现一些人在谈论名为 IIS 设置的讨论minBytesPerSecond(此处讨论: https: //social.msdn.microsoft .com/Forums/en-US/aeb01c46-bcdf-40ed-a417-8a3558221137)。我还发现了另一个讨论,其中存在一些关于是否minBytesPerSecond旨在防止慢速 HTTP DoS(慢速滴注)攻击的争论(此处讨论:IIS 8.5 低 minBytesPerSecond 不适用于慢速 HTTP POST)。无论如何,我了解到 IIS 用于minBytesPerSecond确定在无法维持最小吞吐量时是否取消连接。这在以下情况下是相关的:单个用户向大型资源发出许多请求,并且每个新连接最终都会导致所有其他未完成的连接挨饿,以至于某些连接可能会低于minBytesPerSecond。
  2. 为了确认服务器由于minBytesPerSecond错误而取消请求,我检查了服务器的HTTPERR日志(位于 )c:\windows\system32\logfiles\httperr。果然,我打开该文件并进行了“MinBytesPerSecond”的文本搜索,其中有大量条目。

在此输入图像描述

  1. 因此,在我将 更改为 后minBytesPerSecond,0我不再能够重现该ERR_HTTP2_PROTOCOL_ERROR错误。因此,该ERR_HTTP2_PROTOCOL_ERROR错误似乎是由我的服务器 (IIS) 取消请求引起的,因为我的服务器的吞吐量低于阈值minBytesPerSecond。

因此,对于您现在正在阅读本文的所有人来说,如果您没有使用 IIS,也许有一个与最小吞吐量相关的类似设置,您可以尝试看看它是否可以消除错误ERR_HTTP2_PROTOCOL_ERROR。


Ale*_*kov 43

就我而言,它是 - Web 服务器上没有剩余的磁盘空间。

  • 只是为了向任何想知道为什么这会导致协议错误的人解释一下,因为我们也得到了类似的东西,并且想知道发生了什么。问题是,当磁盘上没有剩余磁盘空间时,某些网络服务器(当然是 nginx,但也可能是 apache)无法发送整个响应,通常只是在发送响应的第一个“chuck”后丢弃请求。这会导致内容长度标头与收到的实际内容不匹配。这(如 @Xtendo 所提到的)可能会导致 http2 协议错误。 (3认同)

Bri*_*kad 19

在研究了一些我认为导致 24 个错误的错误后,我终于能够解决这个错误。我访问了网络上的所有页面。我很高兴地说我找到了解决方案。如果您使用的是 NGINX,则将 gzip 设置为 off 并添加proxy_max_temp_file_size 0;服务器块,如下所示。

 server {
  ...
  ...
  gzip off;
  proxy_max_temp_file_size 0;
  location / {
    proxy_pass http://127.0.0.1:3000/;
  ....
Run Code Online (Sandbox Code Playgroud)

为什么?因为实际发生的是所有内容都被压缩了两次,我们不希望那样,对吧?!

  • 欣赏这一点!我认为在我的特定情况下关闭“gzip”是缺少的步骤。我在 nginx 后面运行一个 Express 应用程序,并且只会在 `.css/.js` 上收到错误,但并不总是如此,也许只有 1/2 的时间。这招成功了! (2认同)
  • 只是 proxy_max_temp_file_size 0; 声明对我来说效果很好。 (2认同)

小智 17

几个星期以来,我也对这个“错误”感到恼火:

net :: ERR_HTTP2_PROTOCOL_ERROR 200
Run Code Online (Sandbox Code Playgroud)

就我而言,它发生在 PHP 生成的图像上。

它是header()水平的,特别是在这一点上:

header ('Content-Length:'. Filesize($cache_file));
Run Code Online (Sandbox Code Playgroud)

它显然没有返回确切的大小,所以我删除了它,现在一切正常。

所以 Chrome 会检查通过 headers 传输的数据的准确性,如果不对应,则失败。

编辑

我发现为什么content-length通过filesize正在失算了:在GZIP压缩上的PHP文件活跃,因此不包括在问题将解决这个问题的文件。将此代码放在.htaccess:

SetEnvIfNoCase Request_URI ^ / thumb.php no-gzip -vary
Run Code Online (Sandbox Code Playgroud)

它有效,我们保留了 header Content-length。

  • 我遇到了 Livewire 未在共享托管中加载其 JS 的问题,而我可以毫无问题地在浏览器中打开相同的路径。我不明白为什么这有效,但它确实有效。黑魔法。谢谢。 (2认同)

Jai*_*mar 10

我遇到了类似的问题,我在 HTTP GET 请求之一上收到 ERR_HTTP2_PROTOCOL_ERROR。

我注意到 Chrome 更新正在等待中,所以我将 Chrome 浏览器更新到最新版本,下次重新启动浏览器时错误消失了。


Tri*_*n G 6

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

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

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

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

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

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


小智 6

我遇到这个是因为 http2 服务器在向 Chrome 发送大响应时关闭了连接。

为什么?因为它只是 http2 服务器的一个设置,名为WriteTimeout。


No1*_*ver 6

当我有一个将 node-js 应用程序暴露给外部世界的 Nginx 服务器时,我遇到了这个问题。Nginxgzip使用 Chrome 和 Chrome压缩了文件(css、js、...),它看起来是一样的。

发现node-js服务器也用gzip压缩了内容,问题就解决了。在某种程度上,这种双重压缩导致了这个问题。取消 node-js 压缩解决了这个问题。

  • 有趣的是,已经有几个人回答了这篇文章,而且每次问题的根源都是不同的。我认为这个错误确实令人困惑。 (20认同)

Gus*_*ros 5

我的问题是我的访问令牌太大,使得标头也太大,所以我重构了它的内容来修复错误

  • 这也是我的问题。我在本地主机上运行了多个站点,所有站点都在那里存储 cookie。您只需要少量访问令牌即可超过默认的 16KB maxrequestbytes 设置。 (2认同)

归档时间:

查看次数:

17657 次

最近记录:

6 年,10 月 前