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

React如何从NodeJS服务器下载文件?下载后PDF损坏问题怎么解决?

问题根因及解决方案

核心错误

你前端的axios请求参数配置错误:responseType: "blob" 是axios请求的根级配置项,不属于请求头字段,放在headers中完全不会生效,导致axios默认将返回的二进制PDF流当做普通文本解析,文件格式被破坏,因此无法打开。

修复方案

前端代码修改

调整axios配置结构,同时可以做两处可选优化:

  1. 将responseType移到headers同级的配置项中
  2. 创建Blob时明确指定MIME类型为application/pdf,提升兼容性
  3. (可选)用URL.createObjectURL替代FileReader,简化代码逻辑,同时避免内存泄漏问题

修复后的完整代码如下:

const downloadTraining = async (id) => {
    const JWT = new ClassJWT();
    const axiosReq = axios.create();
    await JWT.checkJWT();
    axiosReq
      .get(`${serverPath}/download-training`, {
        // responseType放在根配置,不是headers里
        responseType: "blob",
        headers: {
          training_id: id,
          token: JWT.getToken(),
        },
      })
      .then((res) => {
        // 明确指定Blob的MIME类型为PDF
        const blob = new Blob([res.data], { type: 'application/pdf' });
        const blobUrl = URL.createObjectURL(blob);
        const link = document.createElement("a");
        link.href = blobUrl;
        link.setAttribute("download", "file.pdf");
        document.body.appendChild(link);
        link.click();
        // 用完释放BlobURL,避免内存泄漏
        URL.revokeObjectURL(blobUrl);
        document.body.removeChild(link);
      })
      .catch((err) => console.log(err));
  };

服务端可选优化

你当前的服务端代码如果training不存在时没有任何返回,建议补全404逻辑,避免前端请求挂起:

routerTrainer.get("/download-training", verifyJWT, async (req, res) => {
  const { training_id } = req.headers;
  let training = await Training.findOne({
    where: { id: training_id },
  });
  if (!training) {
    return res.status(404).send('培训文件不存在');
  }
  const path = "/home/gonsa02/Disk/Projects/";
  const dirname = "uploads/trainings/";
  res.download(`${path}${dirname}${training.file_id}`);
});

内容的提问来源于stack exchange,提问作者Gonsa02

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:39:02