70

I'm trying to implement long polling for the first time, and I'm using XMLHttpRequest objects to do it. So far, I've been successful at getting events in Firefox and Internet Explorer 11, but Chrome strangely is the odd one out this time.
我第一次尝试实现长轮询,我使用 XMLHttpRequest 对象来实现它。到目前为止,我已经成功地在 Firefox 和 Internet Explorer 11 中获取事件,但奇怪的是,Chrome 这次却与众不同。

I can load one page and it runs just fine. It makes the request right away and starts processing and displaying events. If I open the page in a second tab, one of the pages starts seeing delays in receiving events. In the dev tools window, I see multiple requests with this kind of timing:
我可以加载一个页面,它运行得很好。它立即发出请求,并开始处理和显示事件。如果我在第二个选项卡中打开页面,其中一个页面开始看到接收事件的延迟。在开发工具窗口中,我看到多个具有这种定时的请求:

screenshot

"Stalled" will range up to 20 seconds. It won't happen on every request, but will usually happen on several requests in a row, and in one tab.
“失速”的范围最长可达20秒。它不会发生在每个请求上,但通常会发生在一行中的几个请求上,并且在一个选项卡中。

At first I thought this was an issue with my server, but then I opened two IE tabs and two Firefox tabs, and they all connect and receive the same events without stalling. Only Chrome is having this kind of trouble.
起初我以为这是我的服务器的问题,但后来我打开了两个 IE 标签和两个 Firefox 标签,它们都连接并接收相同的事件,而没有停顿。只有 Chrome 有这样的问题。

I figure this is likely an issue with the way in which I'm making or serving up the request. For reference, the request headers look like this:
我想这可能是我提出或提供请求的方式的问题。作为参考,请求头看起来像这样:

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

The response looks like this:
响应如下所示:

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

In spite of the headers involved, I'm not using the browser's native EventSource, but rather a polyfill that lets me set additional headers. The polyfill is using XMLHttpRequest under the covers, but it seems to me that no matter how the request is being made, it shouldn't stall for 20 seconds.
尽管涉及到头,我没有使用浏览器的本地 EventSource,而是使用一个 polyfill,它允许我设置额外的头。polyfill 在幕后使用 XMLHttpRequest,但在我看来,无论请求是如何发出的,它都不应该停滞 20 秒。

What might be causing Chrome to stall like this?
是什么原因导致 Chrome 如此停滞不前?

Edit: Chrome's chrome://net-internals/#events page shows that there's a timeout error involved:
编辑:Chrome 的 Chrome://net-internals/#events 页面显示存在超时错误:

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

The error message refers to a patch added to Chrome six months ago (https://codereview.chromium.org/345643003), which implements a 20-second timeout when the same resource is requested multiple times. In fact, one of the bugs the patch tries to fix (bug number 46104) refers to a similar situation, and the patch is meant to reduce the time spent waiting.
错误消息指的是六个月前添加到 Chrome 的补丁(https://codereview.chromium.org/345643003),该补丁在多次请求同一资源时实现 20 秒超时。事实上,该补丁试图修复的一个错误( 错误编号 46104)指的是类似的情况,该补丁旨在减少等待时间。

It's possible the answer (or workaround) here is just to make the requests look different, although perhaps Chrome could respect the "no-cache" header I'm setting.
这里的答案(或解决方法)可能只是让请求看起来不同,尽管 Chrome 可能会尊重我设置的“无缓存”头。

CC BY-SA 3.0
Get updates on questions and answers
7

4 Answers 4

60

Yes, this behavior is due to Chrome locking the cache and waiting to see the result of one request before requesting the same resource again. The answer is to find a way to make the requests unique. I added a random number to the query string, and everything is working now.

For future reference, this was Chrome 39.0.2171.95.

Edit: Since this answer, I've come to understand that "Cache-Control: no-cache" doesn't do what I thought it does. Despite its name, responses with this header can be cached. I haven't tried, but I wonder if using "Cache-Control: no-store", which does prevent caching, would fix the issue.

CC BY-SA 3.0
20
  • 1
    Does that mean that if you repeatedly request your site by spamming [F5] on your keyboard Chrome will visually "hang" on loading? Commented Mar 30, 2015 at 20:30
  • 4
    Cache-Control: no-store worked for me! Very helpful nice answer, thank you :D
    – mpyw
    Commented Aug 30, 2016 at 15:26
  • 3
    I was having this issue and Cache-Control: no-cache, no-store worked for me. Big thanks! Commented Feb 3, 2017 at 20:33
  • 3
    I deliberately put in a 10 second "sleep" in the server and found that if I refresh 2 chrome windows with the same url at the same time, the first one takes 10 seconds and the second takes 20. I can see from the server logs that chrome doesn't send the second request until the first has completed, though it shows the status as "pending" in the second window for the whole 20 seconds. This is regardless of HTTP headers. This doesn't happen if the URLs are different or with firefox.
    – Andy
    Commented Feb 18, 2021 at 11:16
  • 2
    accepted answer is not actually working anymore. adding cache-control does not allow parallel requests in newer chrome version (I checked at version 100)
    – Sly
    Commented Apr 12, 2022 at 11:50
2

I have decided to keep it simple and checked the response headers of a website that did not have this issue and I changed my response headers to match theirs:

Cache-Control: max-age=3, must-revalidate
CC BY-SA 4.0
2

adding Cache-Control: no-cache, no-transform worked for me

CC BY-SA 3.0
0

I ran into the same issue. Cache-Control header didn't help. But I just added extra query parameter with random value and made all requests unique. And it worked.

GET /long-polling?rand=123

GET /long-polling?rand=456

Chrome considered them as different requests.

CC BY-SA 4.0

Your Answer


Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.