React如何从NodeJS服务器下载文件?下载后PDF损坏问题怎么解决?
问题根因及解决方案
核心错误
你前端的axios请求参数配置错误:responseType: "blob" 是axios请求的根级配置项,不属于请求头字段,放在headers中完全不会生效,导致axios默认将返回的二进制PDF流当做普通文本解析,文件格式被破坏,因此无法打开。
修复方案
前端代码修改
调整axios配置结构,同时可以做两处可选优化:
- 将responseType移到headers同级的配置项中
- 创建Blob时明确指定MIME类型为
application/pdf,提升兼容性 - (可选)用
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
相关产品推荐
相关产品推荐

