You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 02:57:23