I want to write a simple server-client code on NodeJS to get the file from server drive:
Route:
app.route('/download/:name').get(file_Controller.download);
Controller:
file_controller.download = async (request, response) => {
const filePath = "file_path"
return response.download(filePath, fileName, (err) => {
if (err) {
console.log(err)
}
});
};
API:
export const fileApi = {
download(params) {
const searchParam = queryString.stringify(params)
const url = `/download/${searchParam}`;
return axiosClient.get(url, {params: {...params}});
},
};
Page:
const download = async () => {
try {
return await fileApi.download({name: "file",});
} catch (error) {
console.log(error);
}
};
If I type the URL directly to browser like http://localhost:3000/download/file
, broswer will let me download the file. However, I don't want to reveal this url to user, so I try to use above code to handle, but have no luck. How should I process?
To download a file, you will need to get response as blob
, then
<a>
element with href linked to the ObjectUrl and click the link.export const fileApi = {
download(params) {
const searchParam = queryString.stringify(params);
const url = `/download/${searchParam}`;
return axiosClient
.get(url, {
params: { ...params },
responseType: 'blob' // important
})
.then(res => {
const href = URL.createObjectURL(res.data); // creates a object url in memory
const link = document.createElement('a');
link.href = href;
link.setAttribute('download', params.name); // name must include a valid file extension
document.body.appendChild(link);
link.click();
document.body.removeChild(link); // removing the link element
URL.revokeObjectURL(href); // Releasing the URL from memory, this is important for optimal performance and memory usage
});
}
};
To download
const download = async () => {
try {
return await fileApi.download({ name: 'file.pdf' });
} catch (error) {
console.log(error);
}
};
Each time you call createObjectURL(), a new object URL is created, even if you've already created one for the same object. Each of these must be released by calling URL.revokeObjectURL() when you no longer need them.