3
for (var i = 0; i < 5; ++i) {
  var xhr;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    xhr = new ActiveXObject("Msxml2.XMLHTTP");
  }
  xhr.open('GET', '/Test/LongOperation?p=' + new Date());
  xhr.send('');
}

これは単なるデモ (ライブ コードではありません) ですが、コアの問題を示しています。 LongOperation10秒後に結果を返すメソッドです。

質問:

  1. 上記のコード スニペットが実行された直後にユーザーがページから移動しようとすると、IE8 (およびおそらく他の IE) がハングするのはなぜですか? FireFox/Safari はこれらの要求をキャンセルし、別のページへのナビゲーションを許可します。then で置き換える'i < 5''i < 4'、IE はハングしません。

  2. この醜い IE の動作を回避するにはどうすればよいですか? ブラウザが突然ハングすると、ユーザーは非常に動揺します。

4

3 に答える 3

3

ほとんどのブラウザーには、特定のサーバーへの接続数が 4 に制限されています。この「問題」を回避する 1 つの方法は、アウト オブ バンド XML リクエストに別のホスト名を使用することです。ユーザー リクエストはメイン ホストに送信され、AJAX リクエストは 2 番目のサーバーに送信されます。

于 2009-05-14T08:25:50.087 に答える
2

私の質問に対する私の答え。window.onbeforeunload内の完了していないxhrオブジェクトをすべて中止します。少なくともこの解決策は私にとってはうまくいきます。$ .ajax()メソッドの動作を少しオーバーライドします。

;(function($) {
    var rq = [];
    var ajax = $.ajax;
    $.ajax = function(settings) {
        // override complete() operation
        var complete = settings.complete;
        settings.complete = function(xhr) {
            if (xhr) {
                // xhr may be undefined, for example when downloading JavaScript
                for (var i = 0, len = rq.length; i < len; ++i) {
                    if (rq[i] == xhr) {
                        // drop completed xhr from list
                        rq.splice(i, 1);
                        break;
                    }
                }
            }
            // execute base
            if (complete) {
                complete.apply(this, arguments)
            }
        }

        var r = ajax.apply(this, arguments);
        if (r) {
            // r may be undefined, for example when downloading JavaScript
            rq.push(r);
        }
        return r;
    };

    // 'kill' all pending xhrs
    $(window).bind('beforeunload', function() {
        $.each(rq, function(i, xhr) {
            try {
                xhr.abort();
            } catch(e) {
                $debug.fail('failed to abort xhr');
            }
        });
        rq = [];
    });
})(jQuery);

$debug-私のユーティリティクラス

于 2009-05-15T15:37:37.047 に答える
0

それらを非同期で実行し、それぞれが完了したときに次の http 要求をトリガーしてみてください。xmlhttp リクエストが IE の UI スレッドをブロックしていると思われますが、他のブラウザーでのその実装はもう少し優雅です。

これで質問 2 の回避策が得られることを願っていますが、質問 1 の本当の理由を推測することしかできません。単なるバグである可能性があります。

于 2009-05-14T08:30:14.117 に答える