1

我正在尝试测量下载/上传速度并同时发出大量 ajax 请求。其中一些由于浏览器连接限制而被阻止,所以我无法通过这样做来建立真正的下载时间:

var start = new Date;
$.get('/data').done(function () {
    console.log(new Date - start);
});

所以,我以这种方式使用原始 xhr:

var open, start, end;
var req = new XMLHttpRequest();
req.open('GET', '/data', true);
req.onreadystatechange = function () {
    switch (this.readyState) {
        case 2:
        case 3:
            if (!start) { start = new Date(); }
            break;
        case 4:
            if (!end) { end = new Date(); }
            console.log('%d: pending = %d, download = %d, total = %d', i, start - open, end - start, end - open);
            break;
    }
};
if (!open) { open = new Date(); }
req.send();

有没有办法使用 jQuery 做同样的事情?

更新

我不需要start在 ajax 请求之前进行初始化,而是在requestState更改为 2 或 3(实际上是下载/上传)之后进行初始化。

更新#2

jQuery bugtracker 中存在相关问题:http: //bugs.jquery.com/ticket/9883

4

1 回答 1

6
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
    if ( options.onreadystatechange ) {
        var xhrFactory = options.xhr;
        options.xhr = function() {
            var xhr = xhrFactory.apply( this, arguments );
            function handler() {
                options.onreadystatechange( xhr, jqXHR );
            }
            if ( xhr.addEventListener ) {
                xhr.addEventListener( "readystatechange", handler, false );
            } else {
                setTimeout( function() {
                    var internal = xhr.onreadystatechange;
                    if ( internal ) {
                        xhr.onreadystatechange = function() {
                            handler();
                            internal.apply( this, arguments ); 
                        };
                    }
                }, 0 );
            }
            return xhr;
        };
    }
});    

var start = null;
var xhr = $.ajax({
   url: "/data",
   complete: function() {
      var end = new Date().getTime();
      var requestTime = end - start;
      console.log(requestTime);
   }
   onreadystatechange: function(xhr) {
      if(xhr.readyState == 3 && start == null) {
         start = new Date().getTime();
      }
   }
});

使用jQuery.ajax()方法complete触发回调successerror(在这些回调之后......如果您想使用这些回调,请使用单独的回调)。

更新(查看您的评论):使用来自此处的代码:https ://gist.github.com/chrishow/3023092利用该.ajaxPrefilter()方法,我们可以向该方法添加一个onreadystatechange选项.ajax()

于 2013-05-14T16:49:52.113 回答