net::ERR_HTTP2_PROTOCOL_ERROR 是关于什么的?

What's the net::ERR_HTTP2_PROTOCOL_ERROR about?

我目前正在开发一个网站,该网站会在 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 提要并且错误消失

Google Chrome 是唯一触发错误的网络浏览器:它在 Edge 和 Firefox 上运行良好。 (注意:我尝试使用 Safari,但出现了类似的 kcferrordomaincfnetwork 303 错误)

我想知道它是否与服务器的 header returned 有关,因为错误中提到了这个“200”,而 404 / 500 页面不是触发任何事情。

问题是根本没有记录错误。 Google 搜索结果很少。此外,我注意到它出现在最近的 Google Chrome 版本中;该错误不会在 v.64.X 上弹出,但会在 v.75+ 上弹出(无论 OS;我正在处理 Mac)。


可能与 Website OK on Firefox but not on Safari (kCFErrorDomainCFNetwork error 303) neither Chrome (net::ERR_SPDY_PROTOCOL_ERROR)

有关

进一步调查的结果如下:

根据要求,下面是失败资源的 returned header,它是整个网页。即使错误是在每个具有 HTTP header 200 的页面上触发的,这些页面始终会加载到客户端的浏览器中,但有时会丢失一个元素(在我的示例中,外部 Twitter 提要)。 “网络”选项卡上的所有其他资产都成功 return,除了整个文档本身。

Google Chrome header (有错误):

Firefox header(无错误):

控制台中的 curl --head --http2 请求 return 如下成功:

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,它将停止向客户端发送数据帧,从而停止响应(或下载)。连接仍然可用于其他请求,并且 requests/responses 与已经中止的可能会继续进步。 [...] 有可能在 RST_STREAM 从客户端传输到服务器时,请求的全部内容都在传输中并将到达客户端,客户端将丢弃它。但是,对于较大的响应内容,发送 RST_STREAM 可能有很好的机会在发送整个响应内容之前到达服务器,因此会节省带宽。"

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

我没弄清楚到底发生了什么,但我找到了解决办法。

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

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

我认为它强制 Apache 使用 HTTP2 协议,但我不明白的是我的每个 headers 中确实提到了 HTTP2,我认为这意味着服务器正在使用正确的协议。

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

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

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

我注意到 Chrome 更新尚未完成,所以我将 Chrome 浏览器更新到最新版本,下次重新启动浏览器时错误消失了。

我在发布大于 1MB 的文件时遇到了同样的问题(asp,c# - HttpPostedFileBase)(即使应用程序对文件大小没有任何限制),对我来说简化模型 class 有帮助。如果您遇到此问题,请尝试删除模型的某些部分,看看是否有任何帮助。听起来很奇怪,但对我有用。

几个星期以来,我也对此感到恼火 "bug":

net :: ERR_HTTP2_PROTOCOL_ERROR 200

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

它处于 header() 水平,尤其是在这一水平上:

header ('Content-Length:'. Filesize($cache_file));

它显然不是 return 确切的大小,所以我删除了它,现在一切正常。

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

编辑

我发现了为什么 content-length 通过 filesize 计算错误:GZIP 压缩在 PHP 文件上处于活动状态,因此排除有问题的文件将修复问题。将此代码放在 .htaccess:

SetEnvIfNoCase Request_URI ^ / thumb.php no-gzip -vary

有效,我们保留 header Content-length

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

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

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

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

我上周一直遇到这个问题,因为我一直试图通过 AJAX 向我的 PHP 服务器发送 DELETE 请求。我最近升级了我的托管计划,现在我的主机上有一个 SSL 证书,用于存储 PHP 和 JS 文件。自从添加 SSL 证书后,我不再遇到此问题。希望这有助于解决这个奇怪的错误。

在我的例子中是 - 网络服务器上没有剩余磁盘 space。

我也遇到过这个错误,我相信背后可能有多种原因。我的是,ARR 超时了。

在我的例子中,浏览器向我设置了重定向规则的反向代理站点发出请求,并且该代理站点最终请求实际站点。现在对于大量数据,它花费了超过 2 分 5 秒,我的服务器的应用程序请求路由超时设置为 2 分钟。我通过以下步骤增加 ARR 超时来解决此问题: 1.进入IIS 2.点击服务器名称 3. 单击中间窗格中的 Application Request Routing Cache 4. 单击右窗格中的服务器代理设置 5.增加超时时间 6. 点击应用

在我们的案例中,原因无效 header。 如编辑 4 中所述:

  • 获取日志
  • 在查看器中选择 事件
  • 选择HTTP2_SESSION

寻找类似的东西:

HTTP2_SESSION_RECV_INVALID_HEADER

--> error = "Invalid character in header name."

--> header_name = "charset=utf-8"

我多次遇到这个错误,这是由于从服务器向客户端传输大量资源(大于 3MB)。

我的团队在我们提供的单个 javascript 文件中看到了这一点。每个其他文件都工作正常。我们从 http2 切换回 http1.1,然后是 net::ERR_INCOMPLETE_CHUNKED_ENCODINGERR_CONTENT_LENGTH_MISMATCH。我们最终发现有一个公司过滤器 (Trustwave) 错误地检测到 "infoleak"(我们怀疑它在我们的 file/filename 中检测到类似于社会安全号码的内容)。让公司调整此过滤器解决了我们的问题。

目前正在修复此错误:https://chromium-review.googlesource.com/c/chromium/src/+/2001234

但它帮助了我,改变了 nginx 设置:

  • 正在打开 gzip;
  • add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
  • 过期了;

就我而言,Nginx 充当 Node.js 应用程序的反向代理。

我们在带有长 Base64 字符串的页面上遇到了这个问题。出现这个问题是因为我们使用了CloudFlare.

详情:https://community.cloudflare.com/t/err-http2-protocol-error/119619.

论坛的关键部分post:

After further testing on Incognito tabs on multiple browsers, then doing the changes on the code from a BASE64 to a real .png image, the issue never happened again, in ANY browser. The .png had around 500kb before becoming a base64,so CloudFlare has issues with huge lines of text on same line (since base64 is a long string) as a proxy between the domain and the heroku. As mentioned before, directly hitting Heroku url also never happened the issue.

临时 hack 是在 CloudFlare 上禁用 HTTP/2。

希望其他人可以提供更好的解决方案,不需要在 CloudFlare 上禁用 HTTP/2。

就我的情况而言,此错误是由于在对 parent/child 关系使用 ORM 时从服务器发送的 json 中的循环引用引起的。所以快速简单的解决方案是

JsonConvert.SerializeObject(myObject, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore })

更好的解决方案是创建不包含两边引用的 DTO (parent/child)。

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

 server {
  ...
  ...
  gzip off;
  proxy_max_temp_file_size 0;
  location / {
    proxy_pass http://127.0.0.1:3000/;
  ....

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

默认情况下,nginx 将上传大小限制为 1MB。

使用 client_max_body_size 您可以设置自己的限制,如

location /uploads {
    ...
    client_max_body_size 100M;
} 

您也可以在 http 或服务器块上设置此设置 (See here)。

这解决了我的 net::ERR_HTTP2_PROTOCOL_ERROR

问题

我有另一个案例导致 ERR_HTTP2_PROTOCOL_ERROR 这里还没有提到。我在 IOC (Unity) 中创建了一个交叉引用,其中 class A 引用 class B(通过几层),class B 引用 class A . 我的设计真的很糟糕。但是我为我从 class B 调用的 class A 中的方法创建了一个新的 interface/class,然后清除了它。

就我而言,现在需要 PHP 7.4 的是 WordPress,而我是 运行 7.2。
我一更新,错误就消失了。


再次发生,这次是广告拦截器不喜欢我的图片名称 (yt.pngig.pngurl.png)。我添加了一个前缀,所有加载正常。

我在使用服务器发送事件时遇到了这个问题。当我注意到我用来启动连接的域名包含一个尾部斜杠时,问题就解决了,例如https://foo.bar.bam/ 失败,ERR_HTTP_PROTOCOL_ERROR,而 https://foo.bar.bam 有效。

在我的例子中(windows 上的 nginx 代理一个应用程序,同时自己提供静态资产)页面显示了多个资产,包括 14 张更大的图片;恰好在 60 秒后,这些图像中的大约 5 个显示了这些错误;在我的例子中,它是默认的 send_timeout 60 秒,使这些图像请求失败;增加 send_timeout 使其工作

我不确定是什么导致 windows 上的 nginx 服务这些文件如此缓慢 - 只有 11.5MB 的资源需要 nginx 将近 2 分钟才能服务,但我想它是另一个线程的主题

我不认为这是问题所在,但通过 cPanel 我注意到 PHP 版本是 5.6,将其更改为 7.3 似乎可以解决问题。这是一个 WordPress 网站。我注意到我可以访问图像和通用 PHP 文件,但加载 WordPress 本身导致了错误。

似乎有很多问题可能会导致 ERR_HTTP2_PROTOCOL_ERROR:在我的例子中,这是 php-generated header、Content-Type : text/plain 中的一个小语法错误。您可能会注意到 space 之前的 冒号……就是这样。当冒号紧挨着 header 名称(如 Content-Type: text/plain)时没有问题。只花了一百万小时才弄清楚...错误仅发生在 Chrome 上,Firefox 毫无怨言地加载了 object。

如果简单地重新启动,例如 Chrome Canary,使用新的配置文件解决问题,那么肯定 是Chrome现场测试中的"victim" of a failed Chrome Variation! Yes, there are ways to opt out of being a Guinea pig

以我为例 header 参数不能设置为 null 或空字符串

{
 'Authorization': Authorization  //Authorization can't use null or ''
}

对于那些从搜索引擎登陆的人。

我最近遇到了这个问题,尽管不是 PHP,而是 .NET 和 Angular。我在这里和 IIS 等 MS 支持论坛上尝试了绝大多数建议。最后我不得不通过旧的控制面板重新安装/修复 IIS Express(这恢复了开发证书,我实际上并没有使用 IIS Express)并在应用程序的 HTTPS 绑定下禁用 HTTP/2。当然,这只是针对开发环境。

在我的案例中,问题是 Bitdefender 为我提供了本地 ssl 证书,而网站仍然没有证书。

当我禁用 Bitdefender 并重新加载页面时,实际有效的服务器 ssl 证书被加载,ERR_HTTP2_PROTOCOL_ERROR 消失了。

我的解决方法是将 IIS 中的 minBytesPerSecond 设置为 0。此设置可以在 IIS 配置编辑器的 system.applicationHost/webLimits 中找到。默认设置为 240.

我按照以下步骤解决了这个问题:

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

  1. 我在谷歌上搜索了术语“RST_STREAM”(这似乎是“重置流”的缩写形式),发现一些人讨论了一个名为 [=10= 的 IIS 设置](此处讨论:https://social.msdn.microsoft.com/Forums/en-US/aeb01c46-bcdf-40ed-a417-8a3558221137). I also found another discussion where there was some debate about whether minBytesPerSecond was intended to protect against slow HTTP DoS (slow drip) attacks (discussion here: )。无论如何,我了解到 IIS 使用 minBytesPerSecond 来确定如果无法维持最小吞吐量是否取消连接。这在单个用户对大型资源发出许多请求的情况下是相关的,并且每个新连接最终都会使所有其他未完成的连接挨饿,以至于一些可能低于 minBytesPerSecond 阈值。
  2. 为了确认服务器由于 minBytesPerSecond 错误而取消了请求,我在 c:\windows\system32\logfiles\httperr 检查了服务器的 HTTPERR 日志。果不其然,我打开了文件并进行了文本搜索“MinBytesPerSecond”,其中包含大量条目。

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

所以对于现在阅读本文的所有人,如果您没有使用 IIS,也许有一个与最小吞吐率相关的类似设置,您可以尝试看看它是否摆脱了 ERR_HTTP2_PROTOCOL_ERROR错误。

就我而言,我的计算机(浏览器客户端)上的时间已过时,使用 windows 中的设置对其进行了同步,然后错误消失了

我的 Content-Security-Policy 和我的 nginx.conf 中有换行符,当在 GCP 的 Kube 中的 docker 容器 运行 中使用时产生了这个错误(服务 angular 但我怀疑这是否重要)。

将它们全部放回同一条线上,问题就消失了。

curl -v 帮助诊断。

 http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [content-security-policy], value: [script-src 'unsafe-inline' 'self....

在单独的行上编辑要容易得多,但再也不会了!

写这篇文章是为了帮助遇到同样情况的人。 我使用 .NET Core 6 API + Angular 13。 问题出在我的 JSON 序列化程序选项最大深度上。我增加了问题已解决。

[https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.maxdepth?view=net-6.0][1]

我们的 ASP.Net 应用程序抛出同样的错误。同一服务器上使用相同 SSL 证书的其他应用程序 运行 正常。

令人费解的是,我们的错误是由于 SQL Server Express 数据库达到了 10GB 的限制。我们在 Windows 错误日志中发现了错误。

清除一些表并减小 DB 大小解决错误!

我也遇到了同样的问题,我只是简单地转到帮助 > 关于 Google Chrome 并将其更新到最新版本。

更新过程完成后,这个错误就会消失,我又可以像往常一样浏览任何我想浏览的东西了。