How to monitor progress using XMLHttpRequest (XHR)

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.

You might also like...

Digital Ocean

The simplest cloud platform for developers & teams. Start with a $200 free credit.

Buy me a coffee ☕

If you enjoy reading my articles and want to help me out paying bills, please consider buying me a coffee ($5) or two ($10). I will be highly grateful to you ✌️

Enter the number of coffees below:

✨ Learn to build modern web applications using JavaScript and Spring Boot

I started this blog as a place to share everything I have learned in the last decade. I write about modern JavaScript, Node.js, Spring Boot, core Java, RESTful APIs, and all things web development.

The newsletter is sent every week and includes early access to clear, concise, and easy-to-follow tutorials, and other stuff I think you'd enjoy! No spam ever, unsubscribe at any time.