How to Use onDownloadProgress in Axios

The onDownloadProgress callback in Axios is a built-in configuration option that allows developers to track and handle the progress of incoming data streams during HTTP requests in real time. This article explains the primary function of onDownloadProgress, the data it exposes via progress events, and how to implement it effectively in web applications to calculate download percentages and update user interfaces.

What is the onDownloadProgress Callback?

The onDownloadProgress option is a function passed within the Axios request configuration object. It listens for download progress events dispatched by the browser's underlying XMLHttpRequest (XHR) API whenever a chunk of data is received from the server.

Its primary purpose is to provide visibility into large file transfers—such as images, videos, documents, or large JSON payloads—allowing applications to display loading indicators, progress bars, and transfer statistics to the user.

Structure of the Progress Event

When triggered, the onDownloadProgress callback receives a ProgressEvent (or an Axios-enhanced progress object in newer versions) containing metadata about the download:

  • loaded: The total number of bytes transferred so far.
  • total: The total expected size of the download in bytes (retrieved from the server's Content-Length header). If the header is missing, total may be undefined or 0.
  • progress: A decimal value between 0 and 1 indicating completion (available in Axios v1.x+).
  • rate: Current download speed in bytes per second (Axios v1.x+).
  • estimated: Estimated time remaining in seconds (Axios v1.x+).

Basic Implementation Example

To monitor download progress, attach the onDownloadProgress function to an Axios request:

import axios from 'axios';

axios.get('https://example.com/large-file.zip', {
  responseType: 'blob',
  onDownloadProgress: (progressEvent) => {
    if (progressEvent.total) {
      const percentage = Math.round((progressEvent.loaded * 100) / progressEvent.total);
      console.log(`Download Progress: ${percentage}%`);
    } else {
      console.log(`Downloaded ${progressEvent.loaded} bytes (total size unknown)`);
    }
  }
})
.then((response) => {
  console.log('Download complete:', response.data);
})
.catch((error) => {
  console.error('Download failed:', error);
});

Calculating Download Percentages

To calculate a percentage completion accurately, the server must supply the Content-Length header in its HTTP response.

  1. When Content-Length is present: Use the formula (loaded / total) * 100 to calculate progress and update UI elements like progress bars.
  2. When Content-Length is absent: Indeterminate progress indicators (such as spinners) should be used, while progressEvent.loaded can be displayed to indicate the total data received to that point.

Important Considerations

  • CORS Settings: When making cross-origin requests, the server must expose the Content-Length header using Access-Control-Expose-Headers: Content-Length for the browser to read the total property.
  • Environment Support: The onDownloadProgress callback is primarily designed for browser environments. In Node.js, tracking download progress is typically handled by listening to data events on readable streams instead.