XMLHttpRequest (XHR) allows us to listen to various events that can occur while the HTTP request is being processed. This includes error notifications, periodic progress notifications, request abort notifications, and more.

In this article, you'll learn how to monitor the file download and upload progress using XHR events in JavaScript.

Monitor download progress with XHR

One such event is progress triggered when the downloading starts. For example, when you post something, XMLHttpRequest will first upload our data (the request body) to the server and then downloads the response.

You can use this event with load to track the file download status. Here is an example:

const xhr = new XMLHttpRequest()

// listen for `load` event
xhr.onload = () => {
  console.log(`The transfer is completed: ${xhr.status} ${xhr.response}`)
}

// listen for `error` event
xhr.onerror = () => {
  console.error('Download failed.')
}

// listen for `abort` event
xhr.onabort = () => {
  console.error('Download cancelled.')
}

// listen for `progress` event
xhr.onprogress = event => {
  // event.loaded returns how many bytes are downloaded
  // event.total returns the total number of bytes
  // event.total is only available if server sends `Content-Length` header
  console.log(`Downloaded ${event.loaded} of ${event.total} bytes`)
}

// open and send request
xhr.open('GET', '/download-attachment')
xhr.send()

As you can see above, we have added several event listeners for events that can be triggered while downloading data from the server using the XMLHttpRequest.

The progress event handler, specified by the xhr.onprogress function above, gets the total number of bytes to transfer and the number of bytes transferred so far in the event's total and loaded properties.

Monitor upload progress with XHR

XMLHttpRequest provides progress events for both download and upload transfers. The download events are fired directly on the XMLHttpRequest object, as seen in the above example.

For upload transfers, the events are fired on the XMLHttpRequest.upload object; an object without methods exclusively exists to track upload events.

The upload object provides its own events similar to XMLHttpRequest that can be used to monitor the upload. Here is an example:

const xhr = new XMLHttpRequest()

// listen for `upload.load` event
xhr.upload.onload = () => {
  console.log(`The upload is completed: ${xhr.status} ${xhr.response}`)
}

// listen for `upload.error` event
xhr.upload.onerror = () => {
  console.error('Upload failed.')
}

// listen for `upload.abort` event
xhr.upload.onabort = () => {
  console.error('Upload cancelled.')
}

// listen for `progress` event
xhr.upload.onprogress = event => {
  // event.loaded returns how many bytes are downloaded
  // event.total returns the total number of bytes
  // event.total is only available if server sends `Content-Length` header
  console.log(`Uploaded ${event.loaded} of ${event.total} bytes`)
}

// open request
xhr.open('POST', '/upload-file')

// prepare a file object
const files = document.querySelector('[name=file]').files
const formData = new FormData()
formData.append('avatar', files[0])

// send request
xhr.send(formData)

Read how to upload files using XHR tutorial to see a practical example of uploading files in JavaScript.

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.