# How to monitor progress using XMLHttpRequest (XHR)

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Feb 23, 2020, updated Oct 12, 2022. Topics: JavaScript.
Canonical URL: https://attacomsian.com/blog/xhr-monitor-progress

> Learn how to monitor file download as well as upload progress using XMLHttpRequest (XHR) in JavaScript.

[XMLHttpRequest (XHR)](https://attacomsian.com/blog/http-requests-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:

```javascript
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](https://developer.mozilla.org/en-US/docs/Web/API/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:

```javascript
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](https://attacomsian.com/blog/xhr-node-file-upload) tutorial to see a practical example of uploading files in JavaScript.
