So the express docs have a download function in the following form:
res.download(cvUrl, cvName, function (err) {
if (err) {
// ...
} else {
// ...
}
})
I think this would normally trigger the browser to download the file automatically, with the correct filename, as the response headers are correctly set and I'm receiving a file. But I'm handling the download like this:
this.admin.getCv(cvUrl).then(cv => {
const url = window.URL.createObjectURL(new Blob([cv]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'test'); // how can I access the filename here?
document.body.appendChild(link);
link.click();
})
Is it possible to access the filename (cvName) on the frontend? Adding it as a second parameter seemed like the obvious solution, but didn't work. Any hints would be great,
Thanks,
Nick
**Edit:
import JRS from '../api/jrs';
export default class Admin {
getCv (applicantId) {
return JRS.get(`/admin/cvs/${applicantId}`);
}
}
// JRS.js
import axios from 'axios';
export default axios.create({
baseURL: 'http://localhost:8080',
headers: {
'Content-Type': 'application/json',
},
withCredentials: true
});
The download
method adds a Content-Disposition
header to the response, so you just need to read that.
It looks like your getCv
function makes an HTTP request, extracts the body from the response, then resolves a promise with that body.
You'll need to modify the getCv
function so it:
Content-Disposition
header (how you do that depends on which HTTP API you are using)contentDisposition.match(/filename=(.*)/)
) Then you'll need to change your then
callback so it handles that object instead of expecting the body directly.
That said, it would probably be easier to just link to the URL directly instead of fetching the data with JSON, converting it to a data:
URL, generating a link and triggering a client on it.
This works for accessing the filename and ext, and fixes the problem I was having with axios/streams/unreadable content, in case it helps anyone else.
For the unreadable content, it was important to add the responseType to the request.
// Client side
axios.get('http://localhost:4000/download', {responseType: 'blob'}).then(res => {
downloadFile(res);
}).catch(err => console.log(err));
const downloadFile = (res) => {
const contentDisposition = res.headers['content-disposition'];
const fileName = contentDisposition.split(';')[1].split('=')[1];
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `${fileName}`);
document.body.appendChild(link);
link.click();
}
// Server
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:2000');
res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
next();
});
app.get('/download', (req, res, next) => {
const test = 'sample.doc';
const fileUrl = path.join(__dirname, test);
const fileName = path.basename(fileUrl);
res.header('Content-Disposition', `attachment; filename=${fileName}`);
const myReadableStream = fs.createReadStream(path.join(__dirname, test));
res.status(200);
myReadableStream.pipe(res);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.