長いポーリングを初めて実装しようとしていますが、XMLHttpRequestオブジェクトを使用して実行しています。これまでのところ、FirefoxとInternet Explorer 11でイベントを取得することに成功していますが、Chromeは奇妙なことに今回は奇妙なものです。
1つのページを読み込むことができ、正常に実行されます。要求をすぐに作成し、イベントの処理と表示を開始します。 2番目のタブでページを開くと、ページの1つでイベント受信の遅延が表示され始めます。開発ツールウィンドウに、このようなタイミングで複数のリクエストが表示されます。
「停止」の範囲は最大20秒です。すべてのリクエストで発生するわけではありませんが、通常は複数のリクエストが連続して1つのタブで発生します。
最初はこれがサーバーの問題だと思っていましたが、2つのIEタブと2つの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ではなく、追加のヘッダーを設定できるポリフィルを使用しています。ポリフィルは内部で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)
このエラーメッセージは、6か月前にChromeに追加されたパッチ( https://codereview.chromium.org/3456430 )を指します。これは、同じリソースが20秒の場合にタイムアウトを実装します複数回要求されました。実際、パッチが修正しようとするバグの1つ( バグ番号46104 )は同様の状況を指し、パッチはreduce待機時間。
おそらくChromeが設定している「no-cache」ヘッダーを尊重するかもしれませんが、ここでの答え(または回避策)は単にリクエストの外観を変えることです。
はい、この動作はChromeキャッシュをロックし、同じリソースを再度要求する前に1つの要求の結果を待機しているためです。答えは、要求を一意にする方法を見つけることです。クエリ文字列に乱数を追加しましたが、すべて正常に動作しています。
将来の参考のために、これはChrome 39.0.2171.95でした。
編集:この答え以来、私は「Cache-Control:no-cache」が思っていた通りに動作しないことを理解するようになりました。名前にもかかわらず、このヘッダーを持つ応答はキャッシュできます。試したことはありませんが、キャッシュを防止するdoesである「Cache-Control:no-store」を使用すると問題が解決するのではないかと思います。
Cache-Control: no-cache, no-transform
を追加するとうまくいきました
シンプルに保つことにし、この問題のないWebサイトの応答ヘッダーを確認し、応答ヘッダーをそれらのヘッダーに一致するように変更しました。
Cache-Control: max-age=3, must-revalidate