React前端如何将Node.js返回的Buffer转换为可下载文件
无服务器文件存储的HTML转PDF并前端下载实现
这个需求可以通过后端直接返回PDF Buffer,配合前端将响应转换为Blob触发下载来完成,全程无需在服务器保存文件。以下是具体实现步骤:
后端(Node.js + Express)实现
- 确保已安装依赖:
convert-html-to-pdf和express - 编写POST接口,接收前端传来的HTML内容,转换为PDF Buffer后直接返回:
const express = require('express'); const convertHtmlToPdf = require('convert-html-to-pdf'); const cors = require('cors'); // 处理跨域,前后端域名/端口不同时需要 const app = express(); app.use(cors()); app.use(express.json({ limit: '10mb' })); // 放宽body大小限制,适配大HTML内容 app.post('/convert-to-pdf', async (req, res) => { try { const { htmlContent } = req.body; // 生成PDF Buffer const pdfBuffer = await convertHtmlToPdf.convert(htmlContent); // 设置响应头:指定文件类型为PDF,触发浏览器下载 res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'attachment; filename="generated.pdf"'); // 直接发送Buffer响应,无需写入服务器磁盘 res.send(pdfBuffer); } catch (err) { console.error('PDF转换错误:', err); res.status(500).json({ message: 'PDF转换失败' }); } }); const PORT = 3001; app.listen(PORT, () => console.log(`后端服务运行在端口 ${PORT}`));
前端(React)实现
前端通过请求后端接口,将响应转换为Blob对象,再通过创建临时URL触发浏览器下载:
import React from 'react'; const PdfGenerator = () => { const handleGenerateAndDownload = async () => { // 示例HTML内容,可替换为组件内的动态渲染内容 const dynamicHtml = ` <!DOCTYPE html> <html> <head> <style> h1 { color: #2c3e50; } p { font-size: 16px; line-height: 1.6; } </style> </head> <body> <h1>动态生成的PDF文档</h1> <p>这是通过convert-html-to-pdf工具转换的内容,无需服务器存储文件</p> </body> </html> `; try { const response = await fetch('http://localhost:3001/convert-to-pdf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ htmlContent: dynamicHtml }), }); if (!response.ok) throw new Error('请求出错'); // 将响应转为Blob类型 const pdfBlob = await response.blob(); // 创建临时下载链接 const downloadUrl = window.URL.createObjectURL(pdfBlob); // 创建a标签触发下载 const link = document.createElement('a'); link.href = downloadUrl; link.download = 'generated.pdf'; document.body.appendChild(link); link.click(); // 清理临时资源 window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(link); } catch (err) { console.error('下载失败:', err); alert('PDF生成失败,请重试'); } }; return ( <button onClick={handleGenerateAndDownload} style={{ padding: '8px 16px', cursor: 'pointer' }}> 生成并下载PDF </button> ); }; export default PdfGenerator;
关键注意事项
- 跨域处理:如果前后端部署在不同域名/端口,后端必须配置CORS(如示例中的
cors中间件),否则前端会出现跨域错误。 - 大HTML内容:如果转换的HTML包含大量内容或图片,需调整Express的
express.json的limit参数,避免请求被截断。 - 预览 vs 下载:若希望在浏览器预览PDF而非直接下载,可将后端的
Content-Disposition改为inline; filename="generated.pdf"。
内容的提问来源于stack exchange,提问作者Chris Hansen
相关产品推荐
相关产品推荐

