Node.js通过Axios上传大文件至AWS S3遇网络错误求助
解决方案
针对线上环境使用Axios上传1GB+大文件到AWS S3时,仅上传150MB就中断的问题,可从以下几个方向排查修复:
1. 确认Axios超时设置的有效性
你设置的timeout:12000000(约3.3小时)可能被浏览器或Axios全局配置覆盖:
- 部分浏览器(如Chrome)存在默认的连接超时限制,可通过浏览器开发者工具的Network面板查看请求的实际超时时间;
- 检查是否通过
axios.create设置了全局超时,全局配置会覆盖单个请求的timeout参数。
2. 改用分块上传规避缓冲区限制
大文件一次性通过FormData上传容易触发内存缓冲区溢出,尤其是线上中间层(CDN/负载均衡)可能限制单块数据大小。建议将文件分块后逐个上传:
const CHUNK_SIZE = 100 * 1024 * 1024; // 100MB/块 const file = formData.get('file'); // 从FormData中获取文件 const totalChunks = Math.ceil(file.size / CHUNK_SIZE); async function uploadChunks() { for (let i = 0; i < totalChunks; i++) { const start = i * CHUNK_SIZE; const end = Math.min(start + CHUNK_SIZE, file.size); const chunk = file.slice(start, end); const chunkFormData = new FormData(); chunkFormData.append('file', chunk); chunkFormData.append('chunkIndex', i); chunkFormData.append('totalChunks', totalChunks); chunkFormData.append('fileName', file.name); try { await axios({ url: BASE_URL + "add/course/chunk", withCredentials: true, method: "POST", timeout: 1200000, // 单块上传超时设为20分钟 headers: { "Content-Type": "multipart/form-data" }, data: chunkFormData, onUploadProgress: (e) => { const chunkProgress = Math.round((e.loaded * 100) / e.total); const totalProgress = Math.round(((i * CHUNK_SIZE) + e.loaded) * 100 / file.size); setProgress(totalProgress); } }); } catch (err) { console.error(`第${i+1}块上传失败`, err); throw err; // 可添加重试逻辑 } } // 所有块上传完成后通知后端合并文件 await axios.post(BASE_URL + "add/course/merge", { fileName: file.name, totalChunks: totalChunks }, { withCredentials: true }); setIsLoading(false); setIsUploaded(true); } uploadChunks().catch(err => console.log(err));
注:后端需配合实现分块接收与文件合并接口。
3. 禁用Axios自动序列化,直接流式发送FormData
Axios默认会对FormData做序列化处理,可能导致大文件被全部读入内存。可通过transformRequest跳过序列化,直接流式传输:
axios({ url: BASE_URL + "add/course", withCredentials: true, method: "POST", timeout: 12000000, headers: { "Content-Type": "multipart/form-data" }, data: formData, transformRequest: [data => data], // 直接返回FormData,不做序列化处理 onUploadProgress: (progressEvent) => { let progress = Math.round((progressEvent.loaded * 100) / progressEvent.total); setProgress(progress); } })
4. 排查线上中间层的超时/大小限制
即使Nginx和后端已配置超时,线上的CDN(如Cloudflare、阿里云CDN)或负载均衡器可能存在独立的超时或单块数据限制:
- 登录CDN控制台,检查上传超时时间配置,需设置为大于文件上传所需的预估时间;
- 可将大文件上传路径配置为跳过CDN,直接访问后端服务器。
5. 检查浏览器内存限制
大文件上传时浏览器内存占用过高可能触发中断,可通过开发者工具的Memory面板监控上传过程的内存使用,或更换其他浏览器测试。
内容的提问来源于stack exchange,提问作者azdeviz
相关产品推荐
相关产品推荐

