web-dev-qa-db-de.com

Chrome blockiert, wenn mehrere Anforderungen an dieselbe Ressource gestellt werden.

Ich versuche zum ersten Mal, ein langes Polling zu implementieren, und verwende dazu XMLHttpRequest-Objekte. Bisher war ich erfolgreich darin, Ereignisse in Firefox und Internet Explorer 11 abzurufen, aber Chrome ist diesmal seltsamerweise das Ungewöhnliche.

Ich kann eine Seite laden und es läuft gut. Es stellt die Anforderung sofort und beginnt mit der Verarbeitung und Anzeige von Ereignissen. Wenn ich die Seite in einem zweiten Tab öffne, werden auf einer der Seiten Verzögerungen beim Empfang von Ereignissen angezeigt. Im Dev Tools-Fenster werden mehrere Anfragen mit dieser Art von Timing angezeigt:

screenshot

"Angehalten" kann bis zu 20 Sekunden dauern. Dies geschieht nicht bei jeder Anfrage, sondern in der Regel bei mehreren Anfragen hintereinander und auf einer Registerkarte.

Zuerst dachte ich, dies sei ein Problem mit meinem Server, dann öffnete ich zwei Registerkarten IE und zwei Registerkarten in Firefox, und alle verbinden sich und empfangen dieselben Ereignisse, ohne anzuhalten. Nur Chrome hat solche Probleme.

Ich nehme an, dass dies wahrscheinlich ein Problem mit der Art und Weise ist, wie ich die Anfrage stelle oder versorge. Als Referenz sehen die Anforderungsheader folgendermaßen aus:

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

Die Antwort sieht folgendermaßen aus:

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

Trotz der beteiligten Header verwende ich nicht die native EventSource des Browsers, sondern eine Polyfill, mit der ich zusätzliche Header festlegen kann. Das Polyfill verwendet XMLHttpRequest unter der Decke, aber es scheint mir, dass es, egal wie die Anfrage gestellt wird, nicht für 20 Sekunden stehen bleiben sollte.

Was könnte dazu führen, dass Chrome so blockiert?

Edit: Die Chrome: // Net-Internals/# -Ereignisseite zeigt an, dass ein Timeout-Fehler vorliegt:

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

Die Fehlermeldung bezieht sich auf einen vor sechs Monaten zu Chrome hinzugefügten Patch ( https://codereview.chromium.org/345643003 ), der ein Timeout von 20 Sekunden implementiert, wenn dieselbe Ressource mehrmals angefordert wird. Tatsächlich verweist einer der Fehler, die der Patch zu beheben versucht ( Fehlernummer 46104 ), auf eine ähnliche Situation, und der Patch soll die Wartezeit reduzieren.

Es ist möglich, dass die Antwort (oder Problemumgehung) hier nur darin besteht, dass die Anforderungen anders aussehen, obwohl Chrome möglicherweise den von mir festgelegten "No-Cache" -Header berücksichtigen könnte.

38
fluggo

Ja, dieses Verhalten ist darauf zurückzuführen, dass Chrome den Cache sperrt und auf das Ergebnis einer Anforderung wartet, bevor Sie dieselbe Ressource erneut anfordern. Die Antwort ist, einen Weg zu finden, um die Anforderungen einzigartig zu machen. Ich habe der Abfragezeichenfolge eine Zufallszahl hinzugefügt, und jetzt funktioniert alles.

Für die zukünftige Verwendung war dies Chrome 39.0.2171.95.

Edit : Seit dieser Antwort habe ich verstanden, dass "Cache-Control: no-cache" nicht das tut, was ich gedacht habe. Antworten mit diesem Header können trotz des Namens zwischengespeichert werden. Ich habe es nicht versucht, aber ich frage mich, ob die Verwendung von "Cache-Control: no-store", das do das Zwischenspeichern verhindert, das Problem beheben würde.

29
fluggo

hinzufügen von Cache-Control: no-cache, no-transform hat für mich funktioniert

1
activedecay

Ich habe mich entschieden, es einfach zu halten, und die Antwortheader einer Website überprüft, bei der dieses Problem nicht auftrat, und ich habe meine Antwortheader geändert, um sie ihren anzupassen:

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