You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 21:36:03