如何将表单数据发送至pdfkit生成的iframe内嵌PDF文档
实现方案说明
1. 方案选型说明
推荐使用POST请求实现,GET请求参数挂载在URL上,有2KB~8KB不等的长度限制,仅适合传递极少量参数,且参数会直接暴露在访问日志、浏览器历史记录中,不适合传递表单数据。POST请求支持传递大量表单内容,安全性和兼容性更好。
2. 后端接口改造
首先确保你的Express服务已经配置了请求体解析中间件:处理JSON表单用express.json(),处理form-urlencoded格式表单用express.urlencoded({extended: true})。
路由改造示例如下:
router.post( "/", authCheck, asyncHandler(async (req: express.Request, res: express.Response) => { const doc = new PDFDocument(); let filename = "toto"; filename = encodeURIComponent(filename) + ".pdf"; res.setHeader( "Content-disposition", 'attachment; filename="' + filename + '"' ); res.setHeader("Content-type", "application/pdf"); // 从POST请求体中获取表单字段,字段名和前端提交的表单保持一致即可 const { formContent, userName, submitDate } = req.body; doc.y = 300; // 把表单内容写入PDF doc.text(`用户名称:${userName}`, 50, 50); doc.text(`提交时间:${submitDate}`, 50, 80); doc.text(`表单内容:${formContent}`, 50, 110); doc.pipe(res); doc.end(); }) );
3. 前端调用改造
原来的iframe直接加载GET地址的方式不支持POST请求,所以需要先通过JS发送POST请求拿到PDF的二进制流,再生成临时地址传给iframe:
import { useState, useEffect } from 'react' // 表单提交处理函数 const handleSubmitForm = async (formData: {userName: string, submitDate: string, formContent: string}) => { try { const res = await fetch('/你的PDF路由地址', { method: 'POST', headers: { 'Content-Type': 'application/json', }, // 传递表单数据 body: JSON.stringify(formData), // 如果你的authCheck依赖cookie校验,需要加这行 credentials: 'include' }) const pdfBlob = await res.blob() // 生成临时访问地址 const pdfUrl = URL.createObjectURL(pdfBlob) // 赋值给iframe的src变量 setPdfContent(pdfUrl) } catch (err) { console.error('PDF生成失败', err) } } // 组件卸载时销毁临时地址,避免内存泄漏 useEffect(() => { return () => { if (pdfContent) URL.revokeObjectURL(pdfContent) } }, [pdfContent]) // iframe使用逻辑不变 <iframe className="preview-pdf__container" src={pdfContent} />
4. 轻量场景可选方案(仅少量参数)
如果你的表单只有2~3个短参数,也可以继续用GET方案,把参数拼在URL的查询字符串里,后端通过req.query拿参数即可:
- 前端拼接地址:
const pdfContent =/pdf路由?userName=${encodeURIComponent(userName)}&submitDate=${submitDate}`` - 后端取值:
const { userName, submitDate } = req.query
内容的提问来源于stack exchange,提问作者LiKi
相关产品推荐
相关产品推荐

