Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XHR Progress Only Firing Once

I'm trying to create a progress bar for a file upload, but for some reason, the XHR progress response is only firing once, at the end. However it works 100% fine (fires throughout the file upload) if I have the firebug window open. I'm testing this on localhost.

My code is really long but here's the gist of it:

is_uploading = $.ajax({
  url: "/includes/upload.php?a=" + a_id,
  type: "POST",
  data: formdata,
  processData: false,
  contentType: false,
  dataType: "JSON",
  xhr: function () {
    var xhr = new window.XMLHttpRequest();
    xhr.upload.addEventListener("progress", function (evt) {
      alert('yay');//test to see if the event is firing...this should be alerting A LOT
      if (evt.lengthComputable) {
        //do stuff
      }
    }, false);

    return xhr;
  }

  ...more options here beforesend, success, etc

I've been pulling my hair out for the past few hours over this, so any help would be appreciated. I have no idea why it works with the firebug console open, but only fires at the end if it's closed...

like image 540
Will S. Avatar asked Feb 19 '15 19:02

Will S.


1 Answers

This could be to do with the size of the file being uploaded and/or your upload speed.

If you are uploading something that's relatively small the upload will complete "instantly", not giving the progress event time to fire during the upload, but instead only firing once on completion:

From https://stackoverflow.com/a/5543745/11743318:

While the request entity body is being uploaded and the upload complete flag is false, queue a task to fire a progress event named progress at the XMLHttpRequestUpload object about every 50ms or for every byte transmitted, whichever is least frequent. - W3 XMLHttpRequest Level 2


I've throttled my network to GPRS to illustrate this point here:

One progress event

Multiple progress events

One can see from the images that without throttling the upload happens so quickly that the progress event is only fired once on completion. The progress bar has a transition applied to its width so it doesn't jump to 100% but rather fills smoothly.

However, in the lower image, when throttled to GPRS, one can see that 36 events are fired in total. The browser-specific implementation mentioned in the linked answer is evident here with the event firing for every 2560 bits = 320 bytes transmitted.

like image 181
compuphys Avatar answered Nov 03 '22 19:11

compuphys