net: :ERR_HTTP2_PROTOCOL_ERROR 错误是关于什么的?

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

例如,发生以下情况:

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

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

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

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

  5. 如果我使用 HTTP 访问网站,Twitter 提要就会出现,错误就会消失

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

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

问题是这个错误根本没有记录在案。谷歌搜索给我的结果非常少。此外,我注意到它出现在最近的谷歌浏览器发布版本中; 这个错误在 v.64.X 上没有出现,但是在 v.75 + 上出现了(不管操作系统是什么; 我正在研究 Mac tho)。


可能和 火狐浏览器网站可用,但 Safari 浏览器网站不可用(kCFErrorDomainCFNetwork error 303) ,Chrome 浏览器网站也不可用(net: : ERR_SPDY_PROTOCOL_ERROR)有关


进一步调查的结果如下:

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

根据要求,下面是失败资源的返回标题,也就是整个网页。即使错误在每个有 HTTP 头200的页面上触发,这些页面总是在客户端浏览器上加载,但有时缺少一个元素(在我的例子中,外部 Twitter 提要)。Network 选项卡上的每个其他资产都有成功返回,除了整个文档本身。 line that failed in console

谷歌浏览器头部(有错误) :

Chrome header

Firefox 头部(没有错误) :

Firefox header

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

所描述的行为与我能观察到的是一样的。但是这就意味着浏览器是罪魁祸首,那么我就不明白为什么这种情况会发生在两个相同的页面上,一个有200 响应头,另一个有404 响应头(如果我禁用 JS,情况也是一样)。

480054 次浏览

我不知道到底发生了什么,但我找到了解决办法。

CDN 的 OVH 功能是罪魁祸首。我把它安装在我的主机服务,但针对我的域域名禁用掉了它,因为我不需要它。

不知怎么的,当我启动它的时候,一切都正常了。

我认为它迫使 Apache 使用 HTTP2协议,但是我不明白的是,在我的每个头中确实有一个 HTTP2提示,我推测这意味着服务器使用正确的协议应答。

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

如果有人更清楚这里可能发生了什么,可以说来听听。

我遇到过类似的问题,我在一个 HTTP GET 请求上获得 ERR _ HTTP2 _ PROTOCOL _ ERROR。

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

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

几个星期以来,我也为这个“错误”而烦恼:

net :: ERR_HTTP2_PROTOCOL_ERROR 200

在我的例子中,它发生在 PHP 生成的图像上。

这是在 header()的水平,特别是在这一个:

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

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

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

剪辑

我发现了为什么通过 filesizecontent-length计算错误: 在 PHP 文件上 GZIP压缩是活动的,因此排除有问题的文件将解决这个问题。把这段代码输入 .htaccess:

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

它工作,我们保持头 Content-length

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

为什么? 因为它只是 http2服务器的一个设置,名为 暂停写作

我在使用 Nginx 服务器将 node-js 应用程序公开给外部世界时遇到了这个问题。Nginx 用 gzip和 Chrome 压缩了这个文件(css,js,...)。

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

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

对我来说是的——网络服务器上没有剩余的磁盘空间。

我也面对过这个错误,我相信背后有很多原因。我的是,ARR 被超时了。

在我的例子中,浏览器向一个反向代理站点发出请求,我在那里设置了重定向规则,该代理站点最终请求实际的站点。现在,对于巨大的数据,它需要超过2分钟5秒,我的服务器的应用程序请求路由超时设置为2分钟。我通过以下步骤增加 ARR 超时来解决这个问题: 1. 进入 IIS 点击服务器名称 3. 单击中间面板中的应用程序请求路由缓存 4. 在右窗格中单击“服务器代理”设置 5. 延长超时时间 6. 点击“申请”

在我们的示例中,原因是头部无效。 正如编辑4中提到的:

  • 拿着木头
  • 在查看器中选择 活动
  • 选择了 HTTP2 _ SESSION

寻找类似的东西:

HTTP2 _ SESSION _ RECV _ INVALID _ HEADER

—— > error = “ Header name 中的字符无效”

—— > header _ name = “ Charset = utf-8

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

我的团队在我们提供的一个 javascript 文件中看到了这一点。其他文件都没问题。我们从 http2切换到 http1.1,然后是 net::ERR_INCOMPLETE_CHUNKED_ENCODINGERR_CONTENT_LENGTH_MISMATCH。我们最终发现有一个公司过滤器(Trustwave)错误地检测到了“信息泄露”(我们怀疑它在我们的文件/文件名中检测到了类似于社会安全号码的东西)。让公司调整这个过滤器解决了我们的问题。

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

但改变 nginx 设置对我有帮助:

  • 打开 gzip;
  • Add _ header‘ Cache-Control’‘ no-store,no-cache,must-revalid,xy-revalid,max-age = 0’;
  • 过期;

在我的例子中,Nginx 充当 Node.js 应用程序的反向代理。

我们在使用长 Base64字符串的页面上遇到了这个问题。

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

论坛帖子的关键部分:

在多个浏览器上进行了隐身标签的进一步测试之后,然后 对从 BASE64到一个实际的. png 映像的代码进行更改时, 在任何浏览器中都不会再发生这样的问题。 png 大约有500kb 在成为 base64之前,所以 CloudFlare 有很多问题 之间的代理(因为 base64是一个长字符串) 正如前面提到的,直接命中 Heroku 网址也从来没有发生过这个问题。

临时黑客技术是在 CloudFlare 上禁用 HTTP/2。

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

对于我的情况,这个错误是由于在使用 ORM 处理父/子关系时从服务器发送 json 中的循环引用造成的。所以快速简单的解决办法就是

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

更好的解决方案是创建不包含双方(父/子)引用的 DTO。

我终于能够解决这个错误后,研究一些事情,我认为是造成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/;
....

为什么,因为事实上所有的内容都被压缩了两次我们不想那样,对吧!

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

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

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

您也可以在 http 或服务器块上设置此设置(看这里)。

这修复了 net: : ERR _ HTTP2 _ PROTOCOL _ ERROR 的问题

我有另一个案例,导致 ERR _ HTTP2 _ PROTOCOL _ ERROR,这里还没有提到。我在 IOC (Unity)中创建了一个交叉引用,其中 A 类引用了 B 类(通过几个层) ,B 类引用了 A 类。但是我为类 A 中的方法创建了一个新的接口/类,我从类 B 中调用它,这样就清除了它。

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


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

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

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

我不知道是什么原因导致窗口上的 nginx 服务这些文件如此缓慢-它只有11.5 MB 的资源,nginx 需要将近2分钟来服务,但我猜它是另一个线程的主题

我不相信这是问题所在,但是通过 cPanel 我注意到 PHP 版本是在5.6,并且把它改成7.3似乎可以解决这个问题。这是一个 WordPress 网站。我注意到我可以访问图片和一般 PHP 文件,但是加载 WordPress 本身导致了错误。

似乎有很多问题可能导致 ERR_HTTP2_PROTOCOL_ERROR: 在我的案例中,这是 php 生成的头 Content-Type : text/plain中的一个小语法错误。你可能会注意到空格 之前冒号... 就是它。当冒号紧挨着头名(如 Content-Type: text/plain)时,没有问题。只花了一百万个小时就搞清楚了... ... 这个错误只发生在 Chrome 浏览器上,Firefox 毫无怨言地加载了这个对象。

如果简单地重新启动,比如 Chrome Canary,使用一个新的配置文件就可以解决问题,那么肯定有人会这样做 是 铬变异失败的“受害者”! 是的,在 Chrome 的现场测试中有很多方法可以选择不成为 小白鼠

对我来说 头参数不能设置空字符串或空字符串

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

对于那些从搜索引擎降落。

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

在我的案例中,问题是当网站还没有证书的时候,BitDefense 为我提供了一个本地的 ssl 证书。

当我禁用 BitDefense 并重新加载页面时,实际有效的服务器 ssl 证书被加载,ERR _ HTTP2 _ PROTOCOL _ ERROR 消失了。

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

事实证明,如果服务器到客户端的数据吞吐量低于某个限制,一些 Web 服务器就会切断到客户端的连接。这是为了防止“慢滴”分布式拒绝服务攻击的攻击。然而,当一个无辜的用户同时请求多个资源(比如一个页面上的大量图片) ,服务器被迫为每个请求限制带宽,导致一个或多个请求降低到吞吐量限制以下,从而导致服务器切断连接并在 Chrome 中显示为 net::ERR_HTTP2_PROTOCOL_ERROR时,也会触发这个限制。

例如,如果你同时请求11张 GIF 图片,每张 GIF 是10MB (11 * 10 = 110MB) ,而服务器只能以每秒100MB (每个线程)的速度服务,那么服务器将不得不降低最后一张 GIF 图片的吞吐量,直到前10张完成。如果最后一个 GIF 上的吞吐量减慢到低于 minBytesPerSecond限制,它将切断连接。

enter image description here

我通过以下步骤解决了这个问题:

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

enter image description here

  1. 我在 Google 上搜索了一下“ RST _ STREAM”这个术语(它似乎是“重置流”的缩写形式) ,发现一些人在讨论一个名为 minBytesPerSecond的 IIS 设置(讨论在这里: 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错误正在取消请求,我在 c:\windows\system32\logfiles\httperr检查了服务器的 HTTPERR日志。果不其然,我打开文件,对“ MinBytesPerSecond”进行了文本搜索,发现有大量的条目。

enter image description here

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

因此,对于正在阅读本文的所有人来说,如果您没有使用 IIS,那么可能存在一个与最小吞吐率相关的类似设置,您可以使用它来查看它是否消除了 ERR_HTTP2_PROTOCOL_ERROR错误。

在我的例子中,我的计算机(浏览器客户端)上的时间已经过期,使用窗口中的设置进行同步,然后错误就消失了

我在 nginx.conf 的内容安全策略中有一个换行,当在 Kube 运行的 gCP 码头集装箱中使用时,出现了这个错误(服务角度,但我怀疑这不重要)。

把他们都放在同一条线上,问题就解决了。

卷发 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://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.maxdepth?view=net-6.0][1]

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

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

清除一些表和减少数据库大小解决错误! !

我也得到了同样的问题,我所做的只是简单地去帮助 > 关于谷歌浏览器和更新到最新版本。

在更新过程完成后,这个错误将消失,我可以像平常一样浏览任何我想要的东西。

只是发布在这里,让人们知道,ERR _ HTTP2 _ PROTOCOL _ ERROR 在 Chrome 中也可以是 由 CORS 请求的意外响应引起

在我们的例子中,期权申请成功,但是 下面的 PUT应该上传一个图像到我们的基础设施 被410拒绝了(因为缺少允许上传的配置) ,导致 Chrome 发出 ERR _ HTTP2 _ PROTOCOL _ ERROR。

在 Firefox 中检入时,错误消息更有帮助:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.[...] (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 410.

在这种情况下,我的建议是检查另一种浏览器。

我在 C # NET Core 6中也遇到过同样的问题。我使用方法 WriteAsync将结果写入 body 响应,并返回 Task.CompletedTask

如下:

await ctx.Response.WriteAsync("something to return");
return Task.CompletedTask;

并将其更改为以下代码:

 await ctx.Response.WriteAsync("something to return");
return ctx.Response.CompleteAsync();

而且现在一切正常。

显然,您需要告诉 Response 对象您已经完成了编辑。

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

在我的案例中(HTTPS 协议,PHP) ,原因是:

错误的404头(

header('404 Not found', true);

而不是

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

)-从以前的网页开发者的遗产。

也许硬盘已经装满了。 试试清理。

我清空了浏览器缓存,没用。 然后我用 ipconfig /flushdns刷新 dns 缓存。它工作了!

有用的链接: https://www.youtube.com/watch?v=BYhtTa11ySM