使用Express、Axios和js-file-download下载文件出错,文件无法播放
问题解决方法
文件无法播放的核心原因是Axios默认会将响应数据解析为JSON格式,把二进制音频文件转成了字符串,再还原时就会损坏文件结构。以下是具体修复方案:
方案一:修改前端Axios请求配置
在发送POST请求时,指定responseType为blob(二进制大对象),让Axios正确处理二进制数据:
Axios.post("http://localhost:3001/download", { name: name }, { responseType: 'blob' // 关键配置 }).then((response) => { fileDownload(response.data, `${title}.mp3`); });
这样response.data就是完整的二进制Blob对象,传给js-file-download后生成的文件就能正常播放。
方案二:改用GET请求更规范(可选优化)
文件下载场景更适合用GET请求,后端可以改成GET接口,前端对应调整:
后端修改代码:
const fs = require('fs'); app.get("/download", (req, res) => { let file_name = req.query.name; // 增加路径安全校验,防止路径遍历攻击 const safeFileName = file_name.replace(/[^a-zA-Z0-9-_]/g, ''); const filePath = path.join(__dirname, `files/${safeFileName}.mp3`); // 校验文件是否存在 if (!fs.existsSync(filePath)) { return res.status(404).send("文件不存在"); } res.download(filePath, (err) => { if (err) console.log(err); }); });
前端修改代码:
Axios.get(`http://localhost:3001/download?name=${encodeURIComponent(name)}`, { responseType: 'blob' }).then((response) => { fileDownload(response.data, `${title}.mp3`); });
额外提示
- 后端必须注意路径安全:直接用用户传入的参数拼接路径存在风险,比如用户传入
../malicious可能访问到服务器其他目录,建议通过正则过滤非法字符,只允许指定范围内的文件名。 - 增加文件存在性校验可以避免返回无效响应,提升接口健壮性。
内容的提问来源于stack exchange,提问作者Ever Loser
相关产品推荐
相关产品推荐

