JS ProgressEvent is only fired when finished

纵然是瞬间 提交于 2019-12-21 05:05:24

问题


I am having some problems getting my upload progress bar to work properly.

According to the XMLHttpRequest Level 2 specs, I attached event listeners for loadstart and progress like this:

var xhr = $.ajaxSettings.xhr();
xhr.upload.addEventListener('loadstart', function(e) {progressCallback(0);});
xhr.upload.addEventListener('progress', function (e) {
    progressCallback(e.loaded / e.total);
});    

$.ajax({
    url: url,
    type: 'POST',
    processData: false,
    contentType: false,
    data: formData,
    xhr: function () {
        return xhr;
    }
}).done(function (data) {
    // Finish stuff
})

The file is correctly uploaded but the progress listener is only called once the request is finsished with 100% (e.total == e.loaded)

Is anything wrong with the code above or is it necessary to configure the server in any special way?


回答1:


When the total size of the file can't be determine, e.loaded and e.total are zero. You can check this inside your progress function:

if (evt.lengthComputable) {
    progressCallback(e.loaded / e.total);
}

The server must also send Content-Length which is defined in the specification:

If the length of the HTTP entity body is known through the Content-Length header, initialize the lengthComputable attribute to true and initialize the total attribute to the length.

Please also notice that the progress bar don't work with the file: protocol.

I can really recommend the Mozilla docs which are very extensive - Using XMLHTTPRequest Mozilla Docs




回答2:


I ran into a similar issue myself, where my event handler function for progress events on XMLHttpRequest was executed only once -- when the upload was complete.

The cause of the problem ended up being simple -- in Google Chrome (possibly other browsers too, I did not test), the progress event will only fire in succession if the upload had been running for a second or two. In other words, if your upload finishes quickly, then you'll likely just get one 100% progress event.

Here's an example of code whose progress event only fires once at 100% complete ( https://jsfiddle.net/qahs40r6/ ):

$.ajax({
  xhr: function()
  {
    var xhr = new window.XMLHttpRequest();
    //Upload progress
    xhr.upload.addEventListener("progress", function(evt){
      if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        console.log("Upload ", Math.round(percentComplete*100) + "% complete.");
      }
    }, false);
    return xhr;
  },
  type: 'POST',
  url: "/echo/json/",
  data: {json: JSON.stringify(new Array(20000))}
});

Console output:

Upload  100% complete.

But if you add an extra zero to the size of the array (increasing the payload size by a factor of 10 -- https://jsfiddle.net/qahs40r6/1/):

$.ajax({
  xhr: function()
  {
    var xhr = new window.XMLHttpRequest();
    //Upload progress
    xhr.upload.addEventListener("progress", function(evt){
      if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        console.log("Upload ", Math.round(percentComplete*100) + "% complete.");
      }
    }, false);
    return xhr;
  },
  type: 'POST',
  url: "/echo/json/",
  data: {json: JSON.stringify(new Array(200000))}
});

Then you get the normal progression of progress events:

Upload  8% complete.
Upload  9% complete.
Upload  19% complete.
Upload  39% complete.
Upload  50% complete.
Upload  81% complete.
Upload  85% complete.
Upload  89% complete.
Upload  100% complete.

This behavior depends upon how fast your Internet connection is, so your mileage will vary. For example, if you take the first example and use Chrome Developer Tools to slow your connection to a simulated "Slow 3G", then you will see the series of progress events.

Similarly, if you are developing locally and uploading data to a local web server, you'll likely never see progress events because the upload will finish instantly.



来源:https://stackoverflow.com/questions/15494781/js-progressevent-is-only-fired-when-finished

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!