NodeJS+React实现文件下载,打开下载的PDF报错该如何解决
问题根因
你前端的responseType配置位置错误,该参数是axios的顶层请求配置项,不属于headers字段,你将其放在headers中导致配置不生效,axios默认将二进制响应数据按照UTF-8字符串转码,损坏了PDF的二进制结构,所以下载后的文件无法正常打开。
修复后的前端代码
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生成下载链接,无需额外调用FileReader 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(); // 释放blob临时资源,避免内存泄漏 URL.revokeObjectURL(blobUrl); document.body.removeChild(link); }) .catch((err) => console.log(err)); };
可选优化项
后端返回文件时可以手动指定正确的响应头,同时补充异常处理逻辑,避免接口异常挂起:
routerTrainer.get("/download-training", verifyJWT, async (req, res) => { const { training_id } = req.headers; let training = await Training.findOne({ where: { id: training_id }, }); if (training) { const filePath = `${path}${dirname}${training.file_id}`; // 若支持多种文件类型,可根据文件后缀动态设置Content-Type res.setHeader('Content-Type', 'application/pdf'); res.download(filePath); } else { res.status(404).send('对应培训资料不存在') } });
内容的提问来源于stack exchange,提问作者Gonsa02
相关产品推荐
相关产品推荐

