向同一资源发出多个请求时,Chrome 会停止?

Posted

技术标签:

【中文标题】向同一资源发出多个请求时,Chrome 会停止?【英文标题】:Chrome stalls when making multiple requests to same resource? 【发布时间】:2015-02-15 07:36:17 【问题描述】:

我第一次尝试实现长轮询,我正在使用 XMLHttpRequest 对象来实现它。到目前为止,我已经成功地在 Firefox 和 Internet Explorer 11 中获取了事件,但奇怪的是 Chrome 是这次出现的奇怪事件。

我可以加载一个页面,它运行得很好。它立即发出请求并开始处理和显示事件。如果我在第二个选项卡中打开该页面,其中一个页面开始出现接收事件的延迟。在开发工具窗口中,我看到多个请求具有这种时间:

“停滞”最长可达 20 秒。它不会发生在每个请求上,但通常会发生在连续的多个请求和一个选项卡中。

起初我以为这是我的服务器的问题,但后来我打开了两个 IE 选项卡和两个 Firefox 选项卡,它们都连接并接收相同的事件而不会停止。只有 Chrome 会遇到这种问题。

我认为这可能与我提出或提供请求的方式有关。作为参考,请求标头如下所示:

Connection: keep-alive
Last-Event-Id: 530
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/39.0.2171.71 Safari/537.36
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

响应如下所示:

HTTP/1.1 200 OK
Cache-Control: no-cache
Transfer-Encoding: chunked
Content-Type: text/event-stream
Expires: Tue, 16 Dec 2014 21:00:40 GMT
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 16 Dec 2014 21:00:40 GMT
Connection: close

尽管涉及到标头,但我并没有使用浏览器的原生 EventSource,而是使用允许我设置额外标头的 polyfill。 polyfill 在幕后使用 XMLHttpRequest,但在我看来,无论请求是如何发出的,它都不应该停顿 20 秒。

什么可能导致 Chrome 像这样停止运行?

编辑: Chrome 的 chrome://net-internals/#events 页面显示存在超时错误:

t=33627 [st=    5]      HTTP_CACHE_ADD_TO_ENTRY  [dt=20001]
                --> net_error = -409 (ERR_CACHE_LOCK_TIMEOUT)

错误消息指的是六个月前添加到 Chrome 中的补丁 (https://codereview.chromium.org/345643003),该补丁在多次请求同一资源时实现了 20 秒的超时。事实上,补丁试图修复的错误之一 (bug number 46104) 指的是类似的情况,补丁旨在减少等待时间。

这里的答案(或解决方法)可能只是让请求看起来不同,尽管 Chrome 可能会尊重我设置的“无缓存”标头。

【问题讨论】:

它说46104号没有问题 按照我上面链接的问题底部的那个数字的BUG链接。 或者让我看看现在能不能直接链接:code.google.com/p/chromium/issues/detail?id=46104 这和我在这里的经历一样吗?使用 Chrome 42 youtube.com/watch?v=PYorlA63ZzI&feature=youtu.be&hd=1 在 chrome 75.0.3770.100 中,上述方法均无效 - 有什么想法可以解决这个问题吗? 【参考方案1】:

我决定保持简单,并检查了没有此问题的网站的响应标头,并更改了响应标头以匹配他们的响应标头:

Cache-Control: max-age=3, must-revalidate

【讨论】:

【参考方案2】:

添加 Cache-Control: no-cache, no-transform 对我有用

【讨论】:

【参考方案3】:

是的,这种行为是由于 Chrome 锁定了缓存并在再次请求同一资源之前等待查看一个请求的结果。答案是找到一种使请求独一无二的方法。我在查询字符串中添加了一个随机数,现在一切正常。

为了将来参考,这是 Chrome 39.0.2171.95。

编辑:自从有了这个答案,我开始明白“Cache-Control: no-cache”并没有像我想的那样做。尽管它的名字,带有这个头的响应可以被缓存。我还没有尝试过,但我想知道使用 确实会阻止缓存的“Cache-Control: no-store”是否可以解决问题。

【讨论】:

这是否意味着如果您通过键盘上的垃圾邮件 [F5] 反复请求您的网站,Chrome 会在加载时视觉上“挂起”? 我不这么认为。更像是同时在多个选项卡中加载同一页面。同时向同一个 URL 发出多个请求时会发生缓存挂起。在我的例子中,这些是长轮询响应,所以在第二个请求中,Chrome 会等待第一个请求完成,看看它是否可以重用响应。第一个请求需要超过 20 秒才能完成,Chrome 会等待很长时间才放弃。 Cache-Control: no-store 为我工作!非常有用的好答案,谢谢:D 我遇到了这个问题,Cache-Control: no-cache, no-store 为我工作。非常感谢! 我特意在服务器里放了一个10秒的“睡眠”,发现如果我同时刷新2个相同url的chrome窗口,第一个需要10秒,第二个需要20 . 我可以从服务器日志中看到,chrome 在第一个请求完成之前不会发送第二个请求,尽管它在整个 20 秒内在第二个窗口中显示状态为“待处理”。这与 HTTP 标头无关。如果 URL 不同或使用 firefox,则不会发生这种情况。

以上是关于向同一资源发出多个请求时,Chrome 会停止?的主要内容,如果未能解决你的问题,请参考以下文章

锁的理解

什么是锁?

Chrome 65 - 无法从本地文件向 Flask 发出 POST 请求

从vbscript向Chrome扩展程序发出XML HTTP请求

多个资产向同一个文件名 index.html 发出不同的内容

不执行方法释放锁