How to Download Files with Axios in JavaScript
A common requirement in web applications is to allow users to download files—such as PDFs, images, or CSVs—by clicking a button. When these files need to be fetched from an API, Axios is an excellent tool for the job.
This guide will teach you the modern, standard method for downloading files with Axios. You will learn how to create a reusable async function that fetches a file as a Blob, programmatically triggers a download in the browser, and correctly names the downloaded file.
The Core Logic: Fetching a Blob and Simulating a Click
You cannot directly "save" a file from an Axios response. Instead, you must trigger a download in the browser by simulating a click on a temporary anchor (<a>) tag.
- Fetch the File as a
Blob: Make aGETrequest with Axios, setting theresponseTypeto'blob'. ABlobis a file-like object of immutable, raw data. - Create an Object URL: Use
URL.createObjectURL(blob)to create a temporary, in-memory URL for the downloaded data. - Create and Click a Link: Create an
<a>element, set itshrefto the object URL, add thedownloadattribute to specify the filename, and programmatically click it. - Clean Up: Revoke the object URL to free up browser memory.
The Modern Solution: A Reusable async Download Function
The best practice is to encapsulate this logic into a single, reusable async function.
The Reusable Function:
import axios from 'axios';
/**
* Downloads a file from a URL using Axios.
* @param {string} url The URL of the file to download.
* @param {string} [defaultFilename] The default filename if not provided by the server.
*/
async function downloadFile(url, defaultFilename = 'downloaded-file') {
try {
// 1. Fetch the file as a blob
const response = await axios.get(url, {
responseType: 'blob',
});
// 2. Create an object URL
const objectUrl = window.URL.createObjectURL(response.data);
// 3. Create and click the link
const link = document.createElement('a');
link.href = objectUrl;
link.download = defaultFilename; // A fallback filename
// Try to get the filename from the Content-Disposition header
const disposition = response.headers['content-disposition'];
if (disposition) {
const filenameMatch = disposition.match(/filename="?(.+)"?/i);
if (filenameMatch && filenameMatch[1]) {
link.download = filenameMatch[1];
}
}
document.body.appendChild(link);
link.click();
// 4. Clean up
document.body.removeChild(link);
window.URL.revokeObjectURL(objectUrl);
} catch (error) {
console.error('There was an error downloading the file:', error);
}
}
Practical Example: Downloading a File on Button Click
With our downloadFile utility function, triggering a download from a user event becomes simple and readable.
<button id="download-btn">Download PDF</button>
Solution:
const downloadButton = document.getElementById('download-btn');
const fileUrl = 'http://localhost:3000/example-file.pdf';
downloadButton.addEventListener('click', () => {
console.log('Starting download...');
downloadFile(fileUrl, 'my-custom-name.pdf');
});
A Note on Filenames and the Content-Disposition Header
How does the browser know what to name the downloaded file?
- The
downloadattribute: The value you provide to the<a>tag'sdownloadattribute is a suggestion to the browser for the filename. - The
Content-Dispositionheader: For a more robust solution, the server should send aContent-Dispositionresponse header. This header explicitly tells the browser that the response is an attachment and provides a filename.Content-Disposition: attachment; filename="report-2023-10-27.pdf"
Our reusable function prioritizes the Content-Disposition header if it exists but falls back to the defaultFilename you provide.
A Critical Note on CORS
This fetch-based approach is subject to Cross-Origin Resource Sharing (CORS) policies.
- If you are downloading a file from a different domain than your website, that server must be configured to allow your domain to make requests.
- If the server does not send the correct
Access-Control-Allow-Originheader, the Axios request will fail, and you will see a CORS error in the console. You cannot bypass this from the client-side.
Conclusion
Downloading files with Axios is a multi-step process that is best handled by a clean, reusable function.
- The key is to set the
responseType: 'blob'in your Axios request config. - You must then create an object URL from the blob and use a temporary
<a>tag with thedownloadattribute to programmatically trigger the download. - For robust filename handling, your server should send a
Content-Dispositionheader. - Remember that this method is always subject to browser CORS policies when requesting files from a different domain.