如何在Express/Node中提供PDF并实现客户端按钮下载功能?
服务器端+客户端实现PDF下载方案
服务器端处理
你的pdfBinary是PDF的原始二进制字符串,需要先转成Node.js的Buffer格式,再配合正确的响应头让浏览器识别为PDF文件。直接修改servePDF函数即可:
const servePDF = async (req, res) => { const pdfBinary = '%PDF-1.4 %âãÏÓ 2 0 obj <<ColorSpa ......'; // 将二进制字符串转换为Buffer const pdfBuffer = Buffer.from(pdfBinary, 'binary'); // 设置响应头,告知浏览器这是PDF文件并触发下载 res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'attachment; filename="download.pdf"'); // 发送Buffer作为响应 res.send(pdfBuffer); };
客户端处理
React侧发送GET请求时,要指定接收blob类型的响应,再通过创建临时链接触发下载:
const downloadPDF = async () => { try { // 发送GET请求,指定响应类型为blob const response = await fetch('/api/serve-pdf', { method: 'GET', }); if (!response.ok) { throw new Error('请求失败'); } // 将响应转换为Blob对象 const pdfBlob = await response.blob(); // 创建Blob的临时URL const pdfUrl = URL.createObjectURL(pdfBlob); // 创建a标签模拟点击完成下载 const link = document.createElement('a'); link.href = pdfUrl; link.download = 'download.pdf'; // 指定下载后的文件名 document.body.appendChild(link); link.click(); // 清理临时资源 document.body.removeChild(link); URL.revokeObjectURL(pdfUrl); } catch (error) { console.error('下载失败:', error); // 可在此添加用户可见的错误提示,比如alert('下载失败,请重试') } };
在React组件中用按钮触发该函数:
<button onClick={downloadPDF}>下载PDF</button>
关键说明
- 服务器必须转Buffer:原始二进制字符串直接发送会被Express按文本处理,导致PDF文件损坏,转成Buffer才能保证二进制数据正确传输。
- 客户端用Blob处理:浏览器可直接将Blob转换为可下载的文件链接,避免手动处理二进制字符串的编码问题。
内容的提问来源于stack exchange,提问作者chivs688
相关产品推荐
相关产品推荐

