Retrieving binary file streams from a server and triggering a browser download in a Nuxt application requires handling the response as a Blob. While the @nuxt/http module is a common choice, the native Fetch API provides a built-in alternative without requiring additional dependencies.
When requesting a file, ensuring the browser does not attempt to parse the binary data as text is critical. Below is an implementation using the native fetch API encapsulated within a reusable utility function.
Implementation
Create a helper function to manage the request and download logic. This isolates the file handling mechanism from the component logic.
async function saveFileFromServer(apiPath, outputName) {
try {
const result = await fetch(apiPath);
if (!result.ok) {
throw new Error(`Network response was not ok: ${result.statusText}`);
}
const binaryData = await result.blob();
const objectUrl = window.URL.createObjectURL(binaryData);
const anchor = document.createElement('a');
anchor.style.display = 'none';
anchor.href = objectUrl;
anchor.download = outputName;
document.body.appendChild(anchor);
anchor.click();
// Cleanup DOM and memory
window.URL.revokeObjectURL(objectUrl);
document.body.removeChild(anchor);
} catch (err) {
console.error('File retrieval failed:', err);
}
}
Integrate this helper into a Nuxt component to allow users to initiate the download.
<template>
<div>
<button @click="triggerDownload">Export Data</button>
</div>
</template>
<script>
import { saveFileFromServer } from '~/utils/fileExporter';
export default {
methods: {
triggerDownload() {
const endpoint = '/api/v1/reports/generate';
const filename = 'report.pdf';
saveFileFromServer(endpoint, filename);
}
}
}
</script>
If the backend specifies the filename dynamically via the Content-Disposition header, you can parse the header string from the response to extract the correct filename before creating the Blob.