9

Internet Explorer を使用してアプリケーションを実行しているユーザーが断続的に失敗する問題は、Internet Explorer のバグが原因であることを最近発見しました。このバグは HTTP スタックにあり、IE からの POST リクエストを使用するすべてのアプリケーションに影響するはずです。その結果、要求が約 5 分間 (サーバーの種類と構成によって異なります) ハングしたように見え、その後サーバー側で失敗するという障害が発生します。サーバーがあきらめた後、ブラウザ アプリケーションはポスト リクエストからエラーになります。以下、IEのバグについて詳しく説明します。

私が知る限り、XMLHttpRequest を使用して POST リクエストをサーバーに送信するすべてのアプリケーションで、リクエストが間違ったタイミングで送信された場合に、これが発生します。私はちょうどその時に POSTS を送信しようとするサンプル プログラムを書きました。サーバーが接続を閉じた正確な瞬間に、継続的な POST をサーバーに送信しようとします。間隔は、サーバーから送信された Keep-Alive ヘッダーから取得されます。

IE からサーバーに少し遅延がある場合 (つまり、同じ LAN 上にない場合)、数回の POST の後に問題が発生することがわかりました。それが起こると、IE は非常に激しくロックアップするため、強制終了する必要があります。時を刻む時計は、ブラウザがまだ応答していることを示しています。

http://pubdev.hitech.com/test.post.phpを参照して試すことができます。IE をクラッシュさせる可能性があるため、IE セッションを実行するときに重要な未保存の情報がないように注意してください。

完全なソースはhttp://pubdev.hitech.com/test.post.php.txtで取得できます。PHP があり、永続的な接続用に構成されている任意のサーバーで実行できます。

私の質問は次のとおりです。

  1. この問題に関する他の人々の経験は何ですか?

  2. この問題を回避するための既知の戦略はありますか (「別のブラウザーを使用する」以外に)?

  3. Microsoft は、この問題について、私が見つけた記事 (以下を参照) よりも詳しい情報を提供していますか?

問題は、RFC 2616 セクション 8.1 で説明されているように、Web ブラウザーとサーバーがデフォルトで永続的な接続を使用することです ( http://www.ietf.org/rfc/rfc2616.txtを参照)。)。これは、特に AJAX アプリケーションのパフォーマンスにとって非常に重要であり、無効にしないでください。ただし、サーバーが接続がアイドル状態であると判断し、接続を閉じることを決定すると同時に、ブラウザーが以前に使用された接続で POST の送信を開始する可能性がある小さなタイミング ホールがあります。その結果、ブラウザの HTTP スタックは閉じたソケットを使用しているため、ソケット エラーが発生します。RFC 2616 セクション 8.1.4 は、この状況を予測しており、「...クライアント、サーバー、およびプロキシは、非同期クローズ イベントから回復できなければなりません。クライアント ソフトウェアは、トランスポート接続を再開し、中断された一連の要求をユーザーの操作なしに再送信する必要があります」と述べています。 ...」

これが発生した場合、Internet ExplorerはPOST を再送信しますが、再送信すると要求が壊れます。投稿されたデータの Content-Length を含む POST ヘッダーを送信しますが、データは送信しません。これは不適切なリクエストであり、サーバーは約束されたデータを不特定の時間待機してから、エラーでリクエストを失敗させます。HTTP サーバーをシミュレートする C プログラムを使用して、この失敗を 100% 実証することができました。これは、応答を送信せずに受信 POST 要求のソケットを閉じます。

Microsoft はhttp://support.microsoft.com/kb/895954でこの失敗を認めているよう です。彼らは、それが IE バージョン 6 から 9 に影響を与えると言います。これは、IE 7 以降のすべてのバージョンの IE に同梱されている、この問題に対するホットフィックスを提供します。ホットフィックスは、次の理由で満足できるものではないようです:

  1. regedit を使用して FEATURE_SKIP_POST_RETRY_ON_INTERNETWRITEFILE_KB895954 というキーをレジストリに追加しない限り、有効になりません。これは、ユーザーがしなければならないことではありません。

  2. ホットフィックスは、破損した POST を実際には修正しません。代わりに、ソケットが RFC の予想どおりに閉じられた場合、POST を再送信しようとせずに、すぐにエラーになります。アプリケーションはまだ失敗します。失敗するのが早いだけです。

次の例は、バグを示す自己完結型の php プログラムです。サーバーが接続を閉じた正確な瞬間に、継続的な POST をサーバーに送信しようとします。間隔は、サーバーから送信された Keep-Alive ヘッダーから取得されます。

4

3 に答える 3

6

IE でこの問題が定期的に発生しています。良い解決策はありません。この問題を確実に解決できる唯一の解決策は、Web サーバーのキープアライブ タイムアウトをブラウザーのキープアライブ タイムアウトよりも長くすることです (IE のデフォルトでは 60 秒です)。Web サーバーがより低い値に設定されている状況では、ソケットが閉じられているため、IE が接続を再利用しようとし、TCP RST で拒否される要求を送信する可能性があります。Web サーバーのキープアライブ タイムアウト値が IE のキープアライブ タイムアウトよりも高い場合、IE が接続を再利用することで、ソケットが閉じられないようにします。待ち時間の長い接続では、転送中に費やされる時間が問題になる可能性があるため、待ち時間を考慮する必要があります。

ただし、サーバーのキープアライブを増やすと、アイドル状態の接続がサーバー ソケットを長時間使用することになることに注意してください。そのため、多数の非アクティブなアイドル接続を処理できるようにサーバーのサイズを調整する必要がある場合があります。これは、サーバーが処理できない負荷のバーストをサーバーにもたらす可能性があるため、問題になる可能性があります。

心に留めておくべきもう一つのこと。RFC セクション 8.1.4 に次のように記載されていることに注意してください。 ."

あなたは非常に重要な部分を忘れていました。全文は次のとおりです。クライアント ソフトウェアは、トランスポート接続を再開し、要求シーケンスがべき等である限り、ユーザーの操作なしで中止された要求シーケンスを再送信する必要があります (セクション 9.1.2 を参照)。べき等でないメソッドまたはシーケンスは、自動的に再試行してはなりませんが、ユーザー エージェントは人間のオペレーターにリクエストを再試行する選択肢を提供することができます (MAY)。アプリケーションの意味を理解したユーザー エージェント ソフトウェアによる確認は、ユーザー確認の代わりになる場合があります。リクエストの 2 番目のシーケンスが失敗した場合、自動再試行を繰り返すべきではありません (SHOULD NOT)。

9.1.2 で定義されているように、HTTP POST はべき等ではありません。したがって、レジストリ ハックの動作は、実際には RFC に従って技術的に正しいものです。

于 2014-01-14T21:29:11.587 に答える
0

この問題に遭遇したことはありません。そして、私たちのクライアントは主に IE6 を実行しています。

キープアライブ タイマーの設定が長すぎると思われます。永続的な接続はページの読み込みを高速化することのみを目的としており、Ajax 呼び出しを処理することを意図していないため、ほとんどの人は 1 秒未満に設定します。

キープアライブの設定が長すぎると、IE のクラッシュよりもはるかに深刻な問題に直面することになります - サーバーはソケットを開くためのファイル記述子を使い果たします!*

* 注:ちなみに、HTTP サーバーへの接続を開いたり閉じたりしないことは、サーバーを強制的に開いているソケットの最大制限に到達させようとする、よく知られた DOS 攻撃です。これが、ほとんどのサーバー管理者が接続タイムアウトも構成して、ソケットが長時間開いたままになるのを避ける理由です。

于 2012-11-21T12:44:26.877 に答える
0

いいえ、通常、POST は IE で動作します。あなたが言っていることは問題かもしれませんが、この巨大な投稿に値するほど大きな問題ではありません.

また、POST ajax リクエストを発行するときは、すべてのブラウザの不整合が確実にカバーされるように、jquery を使用してください。

もう 1 つ: IE は広く使用されており、注意を払う必要があるため、「別のブラウザーを使用する」ように指示する人はいません (まあ、IE6 を除いて、いくつかの新しいバージョンでさえ)。

したがって、POSTIE で動作する必要がありますが、予期しないバグのある動作に対処するには、jquery を使用するとよく眠れます。

于 2012-11-15T01:52:32.407 に答える