什么是网络::: ERR_HTTP2_PROTOCOL_ERROR?


36

我目前正在网站上,该网站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 feed,则错误仍然存​​在

  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

编辑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

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

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



显然,我来过这里,并且只有客户端相关的答案,这不是解决方案。
Tristan G

非Chrome浏览器中会发生错误吗?如果不是,那不是客户端(特别是Chrum浏览器)问题吗?
Jaromanda X

1
格式错误的HTTP响应标头。整个网站都没有加载吗?还是仅一项或多项资产?对于使用HTTP / 2时未加载的资产,您是否可以编辑问题以包含HTTP响应中显示的HTTP响应标头?还有适用于Edge / Firefox的for?
巴里·波拉德

1
在那里看不到任何错误,因此怀疑这不是主要要求。还要忽略cookie的事情-不是那样。:试试这个,看看您是否可以计算T出michalspacek.com/...
巴里波拉德

Answers:


7

几个星期来,我也被这个“臭虫”烦死了:

net :: ERR_HTTP2_PROTOCOL_ERROR 200

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

这是header()一个层面,尤其是在这一层面:

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

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

因此,Chrome会检查通过标头传输的数据的准确性,如果不一致,则会失败。

编辑

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

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

它有效,并且保留标题Content-length


1
太棒了,你救了我!但是我仍然不了解真正的问题,就我而言,该错误仅发生在https中,而不发生在http中。
Nico

您好@Nico,是的,我认为这是正常的,仅在https协议中进行声明的大小与浏览器(Chrome)下载的文件的大小之间的验证。很高兴此解决方案可以为您提供帮助!
Xtendo

1
我以某种方式设法使用“ Content -Length”而不是“ Content-Length”。删除空间后,它起作用了。谢谢。
马丁·洛特灵

您好@Martin Lottering非常高兴它现在对您有用!:-)
Xtendo

6

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

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

以某种方式,当我启用它时,一切正常。

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

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

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


清除CDN缓存对我
有用

4

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

为什么?因为它只是http2服务器的设置,所以名为WriteTimeout


4

以我为例-Web服务器上没有剩余磁盘空间。


有趣的是,对我而言,前端Web服务器的磁盘已满。好像nginx不能解决这种情况,因为日志中没有值得注意的东西。
vchrizz

3

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

我注意到Chrome更新正在处理中,因此我将Chrome浏览器更新为最新版本,并且下次重新启动浏览器时该错误消失了。


2

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

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


6
有趣的是,已经有几个人回答了这个帖子,而每次问题的根源都是不同的。我认为这个错误确实令人困惑。
Tristan G

2

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

但这对我有所帮助,更改了Nginx设置:

  • 开启gzip;
  • add_header'缓存控制''不存储,不缓存,必须重新验证,代理重新验证,最大年龄= 0';
  • 到期;

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


这个答案也对我有用。按照此链接docs.nginx.com/nginx/admin-guide/web-server/compression获取正确的语法
Bhargavi Gopalachar

1

当我注册一个新域名,例如example.com(new.example.com)时,这发生在我身上。这个名字不能在我的位置临时解析几个小时,而可以在国外解析。因此,我使用代理来测试net::ERR_HTTP2_PROTOCOL_ERROR在chrome控制台中看到的一些AJAX帖子的网站。数小时后,当该名称可以在本地重新使用时,这些错误就消失了。

我认为该错误的原因是那些AJAX请求没有被我的代理重定向,它只是访问了一个未被本地DNS解析器解析的网站。



0

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


0

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


0

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

就我而言,浏览器正在向反向代理站点发出请求,在该站点中我设置了重定向规则,该代理站点最终正在请求实际站点。现在,对于海量数据,这花费了超过2分钟5秒的时间,而我的服务器的“应用程序请求路由”超时设置为2分钟。我通过以下步骤增加ARR超时来解决此问题:1.转到IIS 2.单击服务器名称3.单击中间窗格中的“应用程序请求路由缓存” 4.单击右窗格中的“服务器代理”设置5.增加超时6 。单击“应用”


0

在我们的例子中,原因是无效的标题。如编辑4中所述:

  • 记录日志
  • 在查看器中选择“ 事件”
  • 选择了HTTP2_SESSION

寻找类似的东西:

HTTP2_SESSION_RECV_INVALID_HEADER

->错误=“标题名称中的字符无效。”

-> header_name =“ charset = utf-8


0

我的团队在我们提供的单个javascript文件中看到了这一点。其他所有文件都工作正常。我们从切换http2http1.1,然后选择net::ERR_INCOMPLETE_CHUNKED_ENCODINGERR_CONTENT_LENGTH_MISMATCH。我们最终发现,有一个公司过滤器(Trustwave)错误地检测到“信息泄漏”(我们怀疑它在我们的文件/文件名中检测到类似于社会保险号的某项)。让公司调整此筛选器解决了我们的问题。


0

我们在Base64字符串较长的页面上遇到了此问题。发生问题是因为我们使用CloudFlare。

详细信息:https : //community.cloudflare.com/t/err-http2-protocol-error/119619

论坛帖子中的关键部分:

在多个浏览器上的隐身选项卡上进行了进一步测试之后,然后将代码从BASE64更改为真实的.png图像,此问题在任何浏览器中都不再发生。.png在成为base64之前大约有500kb,因此CloudFlare在同一行上存在大量文本行(因为base64是长字符串)作为域和heroku之间的代理存在问题。如前所述,直接点击Heroku网址也从未发生过此问题。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.