Node.js如何将上传PDF转换生成的JSON文件解析并发送给客户端
Node.js 上传PDF转JSON后返回客户端的实现方案
现有代码问题排查
你的代码核心问题是异步逻辑时序错误:pdfParser 的PDF解析、fs.writeFile 写本地文件都是异步非阻塞操作,你在调用pdfParser.loadPDF()后立刻执行res.redirect()和res.end(),会直接结束响应,此时JSON文件还没有生成完成,无法执行后续的返回逻辑。
同时你代码中的fileOriginale没有用let/const声明,会变成全局变量,并发请求时会出现变量覆盖的问题,需要先修正。
实现方案
方案1:无需本地持久化,解析完成后直接返回JSON
适合不需要长期保存解析结果的场景,省略写本地文件步骤,性能更高:
app.post("/upload", (req, res) => { upload(req, res, (err) => { if (err) { console.log(err); return res.status(500).send("上传失败:" + err.message); } if (!req.file) { return res.redirect("index.html"); } // 加const避免全局变量污染 const fileOriginale = req.file.originalname; const pdfParser = new PDFParser(); pdfParser.on("pdfParser_dataError", (errData) => { console.error(errData.parserError); return res.status(500).send("PDF解析失败:" + errData.parserError.message); }); pdfParser.on("pdfParser_dataReady", (pdfData) => { // 直接返回JSON数据给客户端 res.json(pdfData); // 如果需要让客户端触发下载,替换成下面的代码: // res.setHeader('Content-disposition', `attachment; filename=${fileOriginale.replace('.pdf','.json')}`); // res.setHeader('Content-type', 'application/json'); // res.send(JSON.stringify(pdfData)); }); pdfParser.loadPDF(__dirname + "/" + fileOriginale.toString()); }); });
方案2:需要本地保存JSON文件,存储完成后返回
如果需要在服务器持久化存储解析结果,把返回逻辑放到fs.writeFile的回调中,确保文件写入完成后再操作:
app.post("/upload", (req, res) => { upload(req, res, (err) => { if (err) { console.log(err); return res.status(500).send("上传失败:" + err.message); } if (!req.file) { return res.redirect("index.html"); } const fileOriginale = req.file.originalname; const pdfParser = new PDFParser(); pdfParser.on("pdfParser_dataError", (errData) => { console.error(errData.parserError); return res.status(500).send("PDF解析失败:" + errData.parserError.message); }); pdfParser.on("pdfParser_dataReady", (pdfData) => { const fileName = fileOriginale.substring(0, fileOriginale.length - 4) + ".json"; const filePath = __dirname + "/" + fileName; fs.writeFile(filePath, JSON.stringify(pdfData), (err) => { if (err) { console.error(err); return res.status(500).send("JSON保存失败:" + err.message); } // 方式1:直接返回JSON内容 res.json(pdfData); // 方式2:跳转到首页并把JSON访问路径作为参数传递,前端自行拉取 // res.redirect(`index.html?jsonFile=${encodeURIComponent(fileName)}`); // 方式3:直接触发JSON文件下载 // res.download(filePath, fileName); }); }); pdfParser.loadPDF(__dirname + "/" + fileOriginale.toString()); }); });
历史JSON文件访问配置
如果需要让客户端访问已经存储的历史JSON文件,可以开启静态资源服务,把JSON存储目录设为静态目录:
// 所有存储在主目录的JSON文件都可以通过 /json/文件名 访问 app.use('/json', express.static(__dirname));
配置完成后,前端就可以通过/json/xxx.json的路径拉取对应JSON文件。
注意事项
- 不要直接用用户上传的原文件名作为存储名,容易出现重名覆盖、路径穿越的安全问题,建议加上时间戳或随机字符串作为前缀。
- 不需要的临时文件要定期清理,避免占用服务器磁盘空间。
内容的提问来源于stack exchange,提问作者prllgu77
相关产品推荐
相关产品推荐

