How to Monitor Client-Side Upload Progress (with XMLHttpRequest)

XMLHttpRequest Upload Progress

Showing a user something like a progress bar during a file upload is handy and let’s them know that stuff is working. Higher level abstractions like fetch don’t really provide a look into how much of a request body has been sent, but good ol’ XMLHttpRequest does.

In order to monitor upload progress, attach an event listener to progress on the upload property.

const req = new XMLHttpRequest();
req.upload.addEventListener('progress', function (event) {
  // fired every time a progress event happens
});
req.open('POST', '/upload', true);
req.send(someFileOrSomething)

The progress event itself has a few useful properties: lengthComputable, total, and loaded. This can be used with something like bootstrap’s progress bars to build a progress indicator.

const progress = document.getElementById('someProgressBar');
const req = new XMLHttpRequest();
req.upload.addEventListener('progress', function (event) {
  // without a computable length, we can't do anything
  if (!event.lengthComputable) {
    return;
  }

  const percent = (e.loaded / e.total) * 100;
  progress.style.width = `${percent}%`;
});

// open, send request, etc