Background
I am generating a PDF on a express server and saving it to a local directory. In the callback I am attempting to send the PDF back to the server so it will download but it appears i the network tab response as what appears to be binary and does not download.
Example
EDIT My Client Side Function Makes Server Request This fetch call hits an express end point that should return a PDF. The express route is below,
function setImage() {
html2canvas(document.querySelector('#chart')).then(canvas => {
canvas.toBlob(
function(blob) {
const url = 'http://localhost:3000/api/v1/pdf';
fetch(url, {
method: 'POST',
headers: {
'Content-type': 'application/octet-stream',
},
body: blob,
})
.then(response => response.json())
.then(success => console.log(success))
.catch(error => console.log(error));
},
'image/png',
1,
);
document.body.appendChild(canvas);
});
}
// Creates PDF and saves it on server at filePath
router.post('/', (req, res, next) => {
pdf.create(html, options).toFile(filePath, err => {
if (err) {
return console.log(err);
}
const stat = fs.statSync('./downloads/report.pdf');
res.contentType('application/pdf');
res.setHeader('Content-Length', stat.size);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=report.pdf');
// *Should force download the file to the browser*
res.download('../downloads/report.pdf', 'report.pdf', function(e) {
if (e) {
// Handle error, but keep in mind the response may be partially-sent
// so check res.headersSent
} else {
// It worked, do something else.
}
});
});
});
EDIT I also tried this on the server it shows the response in the browser but will not download a file.
router.post('/', (req, res, next) => {
const img = req.body;
const filepath = 'uploads/chart.png';
fs.writeFile(filepath, img, err => {
if (err) {
throw err;
}
console.log('The file was succesfully saved!');
});
const html = tmpl.replace('{{chart}}', `file://${require.resolve('../uploads/chart.png')}`);
const options = { format: 'Letter' };
const fileName = 'report.pdf';
const filePath = './downloads/report.pdf';
pdf.create(html, options).toFile(filePath, err => {
if (err) {
return console.log(err);
}
const stat = fs.statSync('./downloads/report.pdf');
res.setHeader('Content-Description', 'File Transfer');
res.setHeader('Content-Length', stat.size);
res.setHeader('Content-type', 'application/octet-stream');
res.setHeader('Content-type', 'application/pdf');
res.setHeader('Content-Type', 'application/force-download');
res.setHeader('Content-disposition', 'attachment;filename=report.pdf');
res.sendFile('/downloads/report.pdf');
});
Example of output in browser
Question
What is the proper way in Express 4 to force a browser to download a PDF?