Node.js 在express route response中发送PDF并强制下载浏览器
背景 我正在express服务器上生成PDF并将其保存到本地目录。在回调中,我试图将PDF发送回服务器,以便下载,但它显示为网络选项卡响应,显示为二进制,不下载 示例 编辑我的客户端功能发出服务器请求 此fetch调用到达一个应该返回PDF的快速端点。快线在下面,Node.js 在express route response中发送PDF并强制下载浏览器,node.js,express,Node.js,Express,背景 我正在express服务器上生成PDF并将其保存到本地目录。在回调中,我试图将PDF发送回服务器,以便下载,但它显示为网络选项卡响应,显示为二进制,不下载 示例 编辑我的客户端功能发出服务器请求 此fetch调用到达一个应该返回PDF的快速端点。快线在下面, function setImage() { html2canvas(document.querySelector('#chart')).then(canvas => { canvas.toBlob( fu
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);
});
}
//创建PDF并将其保存在服务器上的filePath处
编辑我也在服务器上尝试过,它会在浏览器中显示响应,但不会下载文件
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');
});
浏览器中的输出示例
问题
在Express 4中,强制浏览器下载PDF的正确方式是什么 我现在看到了您的问题,fetch使用AJAX在后台执行请求,响应转到您的代码,您捕获它并将其作为JSON写入屏幕。
为了打开文件对话框并下载文件,您需要有一个指向与
相同位置的链接。我测试了您的代码,在我的示例中,它似乎运行良好。它与浏览器选择如何处理这种mime类型有更多关系,指向“下载”的链接放在哪里?你能分享那个代码吗?
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');
});