Vue+Express视频下载接口首请求成功,后续请求报Network Error问题
问题分析与解决方案
可能的原因及对应解决办法
1. Vue组件代码变量重复定义
你的downloadVideo函数参数是fileName,但内部又重新声明了const fileName = fileDir.split('/').pop();,这会导致语法错误,可能影响后续请求的执行。
修改代码:
// 把参数名改为fileDir,避免变量冲突 downloadVideo(fileDir) { const fileName = fileDir.split('/').pop(); const downloadUrl = `/download/videos/${fileName}`; // ... 其余下载逻辑 }
2. Express的res.download可能存在流未正确释放
res.download虽然便捷,但在处理大文件或重复请求时,可能出现文件句柄未释放的问题,导致后续请求无法读取文件。改用手动创建读取流的方式,确保流正确关闭。
修改Express路由代码:
const fs = require('fs'); const path = require('path'); app.get("/download/:kind/:fileName", (req, res) => { const filePath = path.join(__dirname, 'public/files', req.params.kind, req.params.fileName); // 先检查文件是否存在 fs.access(filePath, fs.constants.F_OK, (err) => { if (err) { return res.status(404).send('文件不存在'); } // 创建文件读取流 const readStream = fs.createReadStream(filePath); // 设置响应头,确保浏览器识别为下载文件 res.setHeader('Content-Disposition', `attachment; filename="${req.params.fileName}"`); res.setHeader('Content-Type', 'video/mp4'); // 将流管道到响应对象 readStream.pipe(res); // 处理流读取错误 readStream.on('error', (streamErr) => { res.status(500).send('文件读取失败'); readStream.destroy(); // 销毁流,释放资源 }); // 流结束时关闭资源 readStream.on('end', () => { readStream.close(); }); }); });
3. 浏览器缓存或连接复用问题
浏览器可能缓存了之前的响应,或者同一域名的连接池被占满,导致后续请求失败。可以在请求URL后添加随机时间戳,避免缓存,同时强制建立新连接。
修改Vue请求代码:
downloadVideo(fileDir) { const fileName = fileDir.split('/').pop(); // 添加时间戳参数,避免缓存 const downloadUrl = `/download/videos/${fileName}?t=${Date.now()}`; axios({ method: "get", url: downloadUrl, responseType: 'blob', timeout: 30000 // 设置超时时间,避免请求挂起 }) .then((response) => { const href = URL.createObjectURL(response.data); const link = document.createElement('a'); link.href = href; // 使用原文件名作为下载文件名,更合理 link.setAttribute('download', fileName); document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(href); }) .catch((err) => { console.error('下载错误:', err); }) },
4. 代理配置或CORS细节问题
虽然你已经配置了CORS和代理,但可以明确CORS的origin,确保跨域请求权限正确;同时检查代理是否在后续请求中正常转发。
优化CORS配置:
app.use(cors({ origin: 'http://localhost:8080', // 明确指定前端域名 credentials: true // 若需要携带Cookie可开启,下载场景可选 }));
5. 检查浏览器请求详情
打开浏览器开发者工具的Network面板,查看失败请求的Response和Headers:
- 确认响应状态码确实是200,且Response Body有内容
- 检查
Content-Length是否与文件大小匹配,判断响应是否被截断 - 查看是否有其他错误提示,比如
ERR_CONNECTION_RESET等
内容的提问来源于stack exchange,提问作者ege
相关产品推荐
相关产品推荐

