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

使用@aws-sdk上传S3遇问题:大文件报Failed to fetch,小文件正常

AWS S3大文件上传报错:TypeError: Failed to fetch

问题详情

使用@aws-sdk/client-s3的PutObjectCommand和@aws-sdk/lib-storage向AWS S3存储桶上传文件时,文件大小超过70KB就会触发以下错误,小于该大小的文件可正常上传:

TypeError: Failed to fetch
at FetchHttpHandler.handle (fetch-http-handler.js:56:13)
at PutObjectCommand.js:56:58
at flexibleChecksumsResponseMiddleware.js:17:26
at deserializerMiddleware.js:2:32
at check-content-length-header.js:18:16
at awsAuthMiddleware.js:10:26
at async retryMiddleware.js:24:46
at async flexibleChecksumsMiddleware.js:54:20
at async loggerMiddleware.js:3:26
at async Promise.all (index 0)
upload.ts:31

上传代码如下:

import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";
import { FetchHttpHandler } from "@smithy/fetch-http-handler";

const secretAccessKey = import.meta.env.VITE_AWS_SECRET_ACCESS_KEY;
const accessKeyId = import.meta.env.VITE_AWS_ACCESS_KEY_ID;
const region = import.meta.env.VITE_AWS_DEFAULT_REGION;
const bucket = import.meta.env.VITE_BUCKET_NAME;

const client = new S3Client({
 credentials: { secretAccessKey, accessKeyId },
 region,
 requestHandler: new FetchHttpHandler({
  requestTimeout: 5000
 })
});

export const onUploadFiles = async (file: any) => {
 const upload = new Upload({
  client,
  params: {
   Bucket: bucket,
   Key: file.name,
   Body: file.file,
   ACL: "public-read"
  },
  partSize: 5 * 1024 * 1024
 });
 try {
  upload.on("httpUploadProgress", (progress) => {
   console.log(progress);
  });

  await upload.done();
 } catch (error) {
  console.log(error);
 }
};

export const onUpload = async (file: any, callback: (data: any) => void) => {
 const input = {
  Bucket: bucket,
  Key: file.name,
  Body: file.file,
  ACL: "public-read"
 };
 try {
  const response = await client.send(new PutObjectCommand(input));
  callback(response);
 } catch (error) {
  console.log(error);
 }
};

解决办法

1. 延长请求超时时间

当前设置的requestTimeout: 5000(5秒)过短,大文件上传需要更长时间完成,超时会导致请求失败。建议将超时时间调整为30秒或更久:

const client = new S3Client({
 credentials: { secretAccessKey, accessKeyId },
 region,
 requestHandler: new FetchHttpHandler({
  requestTimeout: 30000 // 30秒
 })
});

2. 检查并修正S3 CORS配置

存储桶的CORS规则可能限制了大文件上传的请求。确保CORS规则允许PUT方法和必要的请求头,示例配置:

<CORSConfiguration>
  <CORSRule>
    <AllowedOrigin>https://your-domain.com</AllowedOrigin> <!-- 替换为实际域名,或用*临时测试 -->
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
  </CORSRule>
</CORSConfiguration>

3. 调整分块上传的partSize

如果网络环境较差,5MB的分块可能容易超时。尝试减小分块大小,比如改为1MB:

const upload = new Upload({
  client,
  params: {
   Bucket: bucket,
   Key: file.name,
   Body: file.file,
   ACL: "public-read"
  },
  partSize: 1 * 1024 * 1024 // 1MB
});

4. 排查浏览器/网络限制

如果是在浏览器环境上传,检查:

  • 浏览器开发者工具的Network面板,查看请求是否有具体的状态码(如403、404)或中断原因
  • 切换网络环境(比如关闭代理、换用手机热点),排除防火墙/代理拦截
  • 确认浏览器没有对大文件上传的限制

5. 验证IAM凭证权限

确保AWS凭证拥有s3:PutObject权限,且资源范围正确:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}

内容的提问来源于stack exchange,提问作者André Henrique

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:55:57