开发者

XHR Upload Progress is 100% from the start

开发者 https://www.devze.com 2023-01-09 00:08 出处:网络
I\'m trying out the new XMLHTTPRequestUpload feature to upload some files to a php script, it mostly works fine, the upload starts, I get the finish response etc - but the progress doesn\'t seem to wo

I'm trying out the new XMLHTTPRequestUpload feature to upload some files to a php script, it mostly works fine, the upload starts, I get the finish response etc - but the progress doesn't seem to work.

Looking that the event.loaded value - In firefox I seem to get a random value between 0 and the file size; in Chrome (where I'm mostly working) I get the total file size, even though the readystate hasn't reached '4' and the Developer Tools window still shows the file to be loading?

Any ideas?

Heres my code:

var xhr = new XMLHttpRequest()

xhr.upload.addEventListener('progress', function(event) {
    if (event.lengthComputable) {
        $('ajaxFeedbackDiv').innerHTML = event.loaded + ' / ' + event.total;
    }
}, false);

xhr.onreadystatechange = function(event) {
    if (event.target.readyState == 4) {
        updateFileList();
    }
};

xhr.open("POST", "_code/upload.php");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("X-File-Type", file.type);
xhr.setRequestHeader("Content-Type", "multipart/form-d开发者_Python百科ata");
xhr(file);

Many thanks

Ben


I also recently had some difficulty setting an event listener for XHR onprogress events. I ended up implementing it as an anonymous function, which works beautifully:

xhr.upload.onprogress = function(evt)
{
    if (evt.lengthComputable)
    {
        var percentComplete = parseInt((evt.loaded / evt.total) * 100);
        console.log("Upload: " + percentComplete + "% complete")
    }
};

I stumbled across a lot of other gotchas along the way, though, so it's quite likely one of those was tripping up my event listener. The only other difference between what you've got there and my setup is that I'm using xhr.sendAsBinary().


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. This is likely what @brettjonesdev was seeing in localhost vs remote prod deployments.


I have similar issue and I found reason. In my case the troublemaker is antivirus (bitdefender) on my PC. When I turn off bitdefender protection, the progress behaves exactly as it should.

0

精彩评论

暂无评论...
验证码 换一张
取 消