失敗後にInternet ExplorerがAjax呼び出しでHTTP投稿本文を送信しないのはなぜですか?


114

次のシナリオを確実に再現できます。

  1. サーバーにAJAXリクエストを送信する小さなHTMLページを作成する(HTTP POSTを使用)
  2. ネットワークから切断して再接続する
  3. 失敗後にIEが生成するパケットを監視する

ネットワーク接続が失敗した後、IEは次のAJAX要求を行いますが、HTTPポストを行うときはHTTPヘッダーのみを送信します(本文は送信しません)。これは部分的なリクエストに過ぎないため、サーバーであらゆる種類の問題を引き起こします。Bingでこの問題をググると、AJAXを使用した「ランダムサーバーエラー」または原因不明のAJAXの失敗について不満を言う人がたくさんいます。

IEは(他のほとんどのブラウザーとは異なり)常にHTTP POSTを2つのTCP / IPパケットとして送信することを知っています。ヘッダーと本文は別々に送信されます。失敗の直後の場合、IEはヘッダーのみを送信します。IEがペイロードを送信することはなく、サーバーは最終的にタイムアウトで応答します。

だから私の質問は-なぜそれがこのように振る舞うのですか?HTTP仕様に基づいて間違っているようで、他のブラウザはこのように動作しません。単なるバグですか?確かに、これは深刻なAJAXベースのWebアプリケーションに大混乱をもたらします。

参考情報:

1分より短いHTTPキープアライブタイムアウトによってトリガーされる同様の問題があり、ここに記載されています。

http://us.generation-nt.com/xmlhttprequest-post-sometimes-fails-when-server-using-keep-aliv-help-188813541.html

http://support.microsoft.com/default.aspx?kbid=831167


6
これは、回答に値する優れた明確な質問です。残念ながら、これは少し外れた話題です。webmasters.stackexchange.comまたはsuperuser.stackexchange.comのほうが良いかどうかはわかりません。
Stephen

3
@ gilly3、私は何かが間違っているに違いないと思います。私はそれを読んで、うなずいていたからです...
Ryley

1
@ gilly3:オランダ語に翻訳すると、「googelen」はオランダ語で「ウェブを検索する」ことを意味する動詞(オランダ語の辞書でも定義されている)であるため、これは正しいでしょう。はい、「googlen」ではなく「googelen」と表記されています。奇妙なことです。つまり、「Googel dit probleemがBingに出会った」というだけです。そしてそれは正しいでしょう。

11
@ gilly3:Bingとは?私はそれをググるつもりです。
ロケットハズマット2011年

5
「なぜこのように振る舞うのですか?」-「マイクロソフトの人々は、大部分は優秀ですが、DEC、Unix、Apple、Commodore、またはその他の背景を通じてデジタル時代に入った私たちの人々とは根本的に異なるプログラミング文化の一部です。そして、私たちの残りの部分が彼らの才能ではなく、複雑で、私たちの残りの部分にとって単純で単純なものの完全な腐敗で不思議に喘ぐようなことをする傾向があります」?
jcomeau_ictx 2011年

回答:


28

この質問に対する明確な答えはないようですので、代わりに経験的データを提供し、それを回避するいくつかの方法を提供します。たぶん一部のMSインサイダーはいつかこれにいくつかの光を当てるでしょう...

  1. サーバーでHTTPキープアライブが無効になっている場合、この問題はなくなります。つまり、HTTP 1.1サーバーは、すべてのAjax要求Connection: Closeに応答の行で応答します。これはIEを満足させますが、すべてのAjaxリクエストが新しい接続を開く原因になります。これは、特に待ち時間の長いネットワークで、パフォーマンスに大きな影響を与える可能性があります。

  2. この問題は、Ajaxリクエストが連続して行われると簡単に引き起こされます。たとえば、Ajaxリクエストを100ミリ秒ごとに実行し、ネットワークステータスが変化すると、エラーを簡単に再現できます。ほとんどのアプリケーションはこのような要求を行わない可能性がありますが、この問題につながる可能性のあるいくつかのサーバー呼び出しが互いに直後に発生する可能性があります。おしゃべりが少ないと、IEが幸せになります。

  3. NTLM認証がなくても発生します。

  4. これは、サーバーのHTTPキープアライブタイムアウトがデフォルト(Windowsではデフォルトで60秒)よりも短い場合に発生します。問題のリンクで提供される詳細。

  5. ChromeやFirefoxでは発生しません。FFは1つのパケットを送信するため、この問題を完全に回避しているようです。

  6. IE 6、7、8で発生します。IE9ベータでは再現できませんでした。


4
この問題を解決する他の方法はありますか?JavaScriptの修正はありますか?私はさまざまなXMLHTTPオブジェクトを調べてみましたが、それでも問題は解決しませんでした。
ベルリンブラウン

11

Microsoft Internet Explorerまたは別のプログラムを使用してre-POST操作を実行すると、 Microsoft KB記事というタイトルのヘッダーデータのみが投稿され、この問題が解決するようです。

この記事では修正プログラムを提供しています。IE8などのそれ以降のブラウザーの場合、ホットフィックスはすでに含まれていると表示されますが、クライアントPCのレジストリ設定で有効にする必要があります。


1
この記事で触れていないIE10でこの問題が発生しています。
ClearCloud8 2013年

6
この記事ではIE11まで言及しているため、これは修正されなかったようです。
ピーター、2015年

IE 8,9,10および11の問題の対応に関連したユーザエージェント-私は本番サイトでこの問題が発生しています信じて
ミルハウス

誰かが回避策を見つけましたか?具体的には、307とFF、Chrome、Safariをデータを新しいエンドポイントに再送信します-IEは送信しません。ユーザーにホットフィックス/レジストリパッチを要求することができません。
Brad Gunn

2

IEの一部の古いバージョンがPOSTの本体ではなくヘッダーのみを返すという同様の問題がありました。私の問題はIEとNTLMに関連していることが判明しました。NTLMについて言及しなかったので、これはおそらく役に立ちませんが、念のために:

http://support.microsoft.com/kb/251404


あなたのリンクはIE 11およびIIS 6で同様の問題の解決に役立ちました
Harminder

1

これは長い話ですが、IE(さらにはFirefox)は、HTTPリクエストに使用する接続を「記憶」することがあります。メモ/例:

  • Firefoxでは、プロキシ設定を変更し、ページでSHIFT-RELOADを押すと、古いプロキシが引き続き使用されます。ただし、古いプロキシ( "killall squid")を強制終了すると、新しいプロキシの使用が開始されます。

  • 切断/再接続すると、新しいIPアドレスまたは同様のものを受け取りますか?古いIPアドレスを何らかの方法で監視して、IEがデータを現在死んでいるアドレスに送信しているかどうかを確認できますか?

  • 私の推測では、IEは間違った経路をたどってデータを送信しています。「POST」パケットのネットワーク接続をキャッシュしないほど賢いかもしれませんが、POSTペイロードの場合は十分に賢くないかもしれません。

  • 人々がネットワークから切断して再接続することはめったにないので、これはおそらくほとんどのAJAXアプリに影響を与えませんか?


2
問題は最後だと思います。Microsoftは「まれにしか発生しない:実装しない」というポリシーを採用していると思います。:)

1
ソースから宛先へのすべてのHTTPトラフィックを監視します。(a)IPアドレスが変更されていないこと、(b)他に何も送信する試みがないことを確認できます。IEは新しいソケットを開き、部分的なリクエストを送信します。私がMSの記事を読む方法は、彼らのセキュリティアップデートの1つがIEを壊したことです。次に、それを修正するパッチを作成しました。ただし、古い「壊れた」方法で動作させたい場合に備えて、このレジストリキーを追加できます。Retry_HeaderOnlyPOST_OnConnectionReset。狂気を理解しようとしているだけです。
Dodgyrabbit、2011年

最後に、定期的にポーリングするAjaxアプリがある場合、たとえば10秒とすると、数時間開いたままにすると、このエラーが必ず発生することがわかります。おそらく、Wi-Fi接続が途切れる、またはネットワークが不完全である可能性がありますが、この問題は非常に現実的です。
Dodgyrabbit、2011年

1

NTLM認証を使用していますか?

NTLM認証を使用する場合、IEはポストデータを送信しません。ヘッダー情報を送信し、許可されていない応答の送信承認を期待し、「再認証」後に投稿を送信します。


NTLM認証は使用しません。匿名のリクエストで発生します。
Dodgyrabbit、2011年

0

$ .ajaxを使用しているときに今日同様の問題があり、asyncをfalseに設定することで修正できました。

$.ajax({
  async: false, 
  url: '[post action url]',
  data: $form.serialize(),
  type: 'POST',
  success: successCallback
});

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.