Download Files as Blobs in the Browser with Axios
Downloading files directly in client-side applications often requires
handling binary data efficiently. This guide outlines the complete
process of using the Axios HTTP client to fetch binary data as a
JavaScript Blob, generate a temporary object URL, and
trigger a seamless file download in the user's browser.
1. Set the Response Type to
blob
By default, Axios parses responses as JSON or plain text. When
requesting a binary file (such as a PDF, CSV, or ZIP), you must
explicitly set the responseType configuration property to
'blob'. This instructs Axios to preserve the raw binary
data as a browser-compatible Blob object.
import axios from 'axios';
const downloadFile = async (url) => {
try {
const response = await axios.get(url, {
responseType: 'blob', // Crucial for binary data
});
return response;
} catch (error) {
console.error('Download failed:', error);
}
};2. Generate a Temporary Object URL
Once Axios resolves the request, the response payload
(response.data) contains the Blob instance.
Use the native window.URL.createObjectURL() method to
create a temporary URL representing the Blob data in the browser's
memory.
const blob = new Blob([response.data], { type: response.headers['content-type'] });
const downloadUrl = window.URL.createObjectURL(blob);3. Programmatically Trigger the Download
Browsers do not automatically prompt a "Save As" dialog when fetching data via JavaScript. To trigger the download action:
- Create a hidden HTML anchor (
<a>) element. - Assign the generated Blob URL to the
hrefattribute. - Specify the desired file name using the
downloadattribute. - Append the anchor to the document body, simulate a click, and remove it.
const link = document.createElement('a');
link.href = downloadUrl;
link.setAttribute('download', 'filename.pdf'); // Set the desired file name
document.body.appendChild(link);
link.click();
link.remove();4. Revoke the Object URL
Object URLs remain in memory until the current document is unloaded
or explicitly released. To prevent memory leaks, call
window.URL.revokeObjectURL() after the download is
initiated.
window.URL.revokeObjectURL(downloadUrl);Complete Implementation Example
Below is a reusable function that handles the complete lifecycle from request to cleanup:
import axios from 'axios';
async function downloadBlobFile(fileUrl, defaultFilename = 'downloaded_file') {
try {
const response = await axios.get(fileUrl, {
responseType: 'blob',
});
// Extract filename from Content-Disposition header if available
let filename = defaultFilename;
const contentDisposition = response.headers['content-disposition'];
if (contentDisposition) {
const filenameMatch = contentDisposition.match(/filename="?(.+)"?/i);
if (filenameMatch && filenameMatch[1]) {
filename = filenameMatch[1];
}
}
// Create a Blob from the response data
const blob = new Blob([response.data]);
const downloadUrl = window.URL.createObjectURL(blob);
// Create a temporary anchor to trigger the download
const link = document.createElement('a');
link.href = downloadUrl;
link.download = filename;
document.body.appendChild(link);
link.click();
// Clean up
link.remove();
window.URL.revokeObjectURL(downloadUrl);
} catch (error) {
console.error('An error occurred during file download:', error);
}
}Handling Error Responses with Blobs
If an API request fails (e.g., returning a 400 or
500 status with a JSON error body), Axios will still
process the error response as a Blob due to the
responseType: 'blob' setting. To read the server's error
message, convert the error Blob back to text:
try {
await axios.get('/api/download', { responseType: 'blob' });
} catch (error) {
if (error.response && error.response.data instanceof Blob) {
const errorText = await error.response.data.text();
const errorJson = JSON.parse(errorText);
console.error('Server error details:', errorJson);
}
}