0

我一直在研究一个使用 html5 和最新版本的 jquery 的 ajax 文件加载器。我对将进度回调与新的基于 Promise 的 ajax 一起使用感到困惑。例如,通知功能。它是自动调用的吗?还是我需要为它编写一个处理程序。在我当前的代码中......显然是摘录。进度回调永远不会被击中。我也意识到有可用的插件,但我不能使用它们。

var ajaxFileUpload = new $.ajax({
            type:'POST',
            url:"/popup/file_upload.php",
            data:_private.appendFormData(file),
            contentType:false,
            processData:false

        }).progress(function (event) {
                console.log(event);
            })
            .done(function (response) {
                console.log("done");


            })
            .fail(function (event) {
                console.log("fail");
            })}};
4

3 回答 3

6

上传进度

如果您想要上传进度条,您可以查看https://github.com/malsup/form/blob/master/jquery.form.js第 292-309 行(这是一个 jquery 插件,但您可以将其取出一小部分供您在没有插件的情况下使用)。

s.xhr = function() {
    var xhr = jQuery.ajaxSettings.xhr();
    if (xhr.upload) {
        xhr.upload.addEventListener('progress', function(event) {
            var percent = 0;
            var position = event.loaded || event.position;
            var total = event.total;
            if (event.lengthComputable) {
                percent = Math.ceil(position / total * 100);
            }
            options.uploadProgress(event, position, total, percent);
        }, false);
    }
    return xhr;
};

下载进度

如果您想要下载进度条,您可以查看http://www.w3.org/TR/progress-events/示例代码。Content-Length我相信, 您的服务器必须在响应标头上提供它才能正常工作。

var progressBar = document.getElementById("p"),
  client = new XMLHttpRequest()
client.open("GET", "magical-unicorns")
client.onprogress = function(pe) {
if(pe.lengthComputable) {
  progressBar.max = pe.total
  progressBar.value = pe.loaded
}
}
client.onloadend = function(pe) {
progressBar.value = pe.loaded
}
client.send()

服务器进度

如果您正在运行需要一段时间的报告并且您想要服务器处理的进度,我是否建议将其更改为多个 ajax 请求:beginFoo, getFooProgress, getFooResult. 其他方法包括使用 COMET 或 Websocket 连接从服务器传达进度,或者在初始 ajax 请求等待响应时单独拉取 web 服务。

注意:html5 中很酷的新 <progress> 元素

如果你想要一个进度 html5 元素:https ://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress 。

于 2013-05-23T20:22:43.553 回答
3

我在 GitHub 上找到了这个来获取jQuery 中的 XHR2 进度事件,带有上传和下载回调:

(function addXhrProgressEvent($) {
    var originalXhr = $.ajaxSettings.xhr;
    $.ajaxSetup({
        xhr: function() {
            var req = originalXhr(), that = this;
            if (req) {
                if (typeof req.addEventListener == "function" && that.progress !== undefined) {
                    req.addEventListener("progress", function(evt) {
                        that.progress(evt);
                    }, false);
                }
                if (typeof req.upload == "object" && that.progressUpload !== undefined) {
                    req.upload.addEventListener("progress", function(evt) {
                        that.progressUpload(evt);
                    }, false);
                }
            }
            return req;
        }
    });
})(jQuery);



// usage:
// note, if testing locally, size of file needs to be large enough
// to allow time for events to fire

$.ajax({
    url: "./json.js",
    type: "GET",
    dataType: "json",
    complete: function() { console.log("Completed."); },
    progress: function(evt) {
        if (evt.lengthComputable) {
            console.log("Loaded " + parseInt( (evt.loaded / evt.total * 100), 10) + "%");
        }
        else {
            console.log("Length not computable.");
        }
    },
    progressUpload: function(evt) {
      // See above
    }
});

通过一些工作,它可以适应调用.progress()延迟回调而不是设置对象中指定的回调。

于 2013-10-28T16:20:40.500 回答
3

不错的选择是使用自定义的 Deferred 重写您的 ajax 函数,这样您就可以为进度方法提供来自 $.Deferred.notify() 的更新。你可能会做这样的事情:

function doAjax() {
  var deferred = $.Deferred();

  $.ajax({
    type:'POST',
    url:"/popup/file_upload.php",
    success: deferred.resolve,  // resolve it 
    error: deferred.reject,  // reject it
    xhrFields: {
      onprogress: function (e) {
        if (e.lengthComputable) {
          deferred.notify(parseInt(e.loaded / e.total * 100), 10);  // notify as a factor of the event object
        }
      }
    }
  }

  return deferred.promise();
}

doAjax()
  .done(function(data) {})
  .fail(function() {} ) 
  .progress(function(value) {  // notify value is available as the param
    console.log('Progress: ', value + "%");  // output
  }
);

将此输出为文本或填充 HTML5 进度元素http://jsbin.com/wevolosa/2/edit?html,console,output

于 2014-02-23T21:17:19.570 回答