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

AWS SDK JS v3 React前端获取PutObject预签名URL参数配置问题

为PutObject操作生成预签名URL(AWS SDK JS v3)

以下配置基于Client与Command模式实现,可直接用于浏览器端图片上传场景。


一、client(S3Client实例)配置

注意:S3Client初始化逻辑必须放在后端服务(Node.js环境)执行,禁止把带AWS密钥的代码打包到前端,否则会泄露云账号权限造成资产损失

  1. 先安装依赖
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
  1. 初始化客户端示例
import { S3Client } from "@aws-sdk/client-s3";

const client = new S3Client({
  region: "你的S3桶所在区域,例如ap-northeast-1",
  credentials: {
    accessKeyId: "你的AWS Access Key ID",
    secretAccessKey: "你的AWS Secret Access Key"
  },
  // 若使用S3兼容存储(如MinIO)可添加以下两个参数,官方AWS S3无需配置
  // endpoint: "你的兼容存储服务地址",
  // forcePathStyle: true
});

生产环境建议把密钥、区域、桶名等配置放到环境变量中,不要硬编码在代码里。


二、putObjectParams(PutObjectCommand入参)配置

该参数用于声明上传对象的属性,常用配置项如下:

const putObjectParams = {
  Bucket: "你的S3桶名称",
  Key: "文件在桶内的存储路径,例如images/avatar/20240501_xxx.png",
  ContentType: "上传文件的MIME类型,例如image/png", // 必配,否则上传后文件默认是二进制流,浏览器访问会触发下载而非预览
  // 可选配置:限制上传文件大小,例如限制最大5MB
  // ContentLength: 5 * 1024 * 1024,
  // 可选配置:若桶为私有读,需要文件公网可访问可添加该配置
  // ACL: "public-read"
};

三、完整实现示例

后端生成预签名URL逻辑(以Express框架为例)

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const client = new S3Client({
  region: process.env.AWS_S3_REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
  }
});

// 给前端调用的签名接口
app.get("/api/get-upload-url", async (req, res) => {
  const { fileName, fileType } = req.query;
  const fileKey = `upload/images/${Date.now()}_${fileName}`;
  const putObjectParams = {
    Bucket: process.env.AWS_S3_BUCKET,
    Key: fileKey,
    ContentType: fileType
  };
  const command = new PutObjectCommand(putObjectParams);
  // expiresIn为签名有效期,单位秒,这里设为5分钟,建议根据业务场景尽量设短
  const uploadUrl = await getSignedUrl(client, command, { expiresIn: 300 });
  res.json({
    uploadUrl,
    // 上传完成后的文件访问地址
    fileUrl: `https://${process.env.AWS_S3_BUCKET}.s3.${process.env.AWS_S3_REGION}.amazonaws.com/${fileKey}`
  });
});

浏览器端上传逻辑

前端拿到后端返回的预签名URL后,直接发送PUT请求上传文件即可,不需要携带额外AWS认证信息:

const fileInput = document.querySelector("#avatarUpload");
fileInput.addEventListener("change", async (e) => {
  const file = e.target.files[0];
  // 向自己的后端请求预签名URL
  const res = await fetch(`/api/get-upload-url?fileName=${encodeURIComponent(file.name)}&fileType=${file.type}`);
  const { uploadUrl, fileUrl } = await res.json();
  // 上传文件到S3
  await fetch(uploadUrl, {
    method: "PUT",
    headers: {
      "Content-Type": file.type // 这里的Content-Type必须和生成签名时填写的ContentType完全一致,否则会报403签名错误
    },
    body: file
  });
  console.log("图片上传完成,访问地址:", fileUrl);
});

常见踩坑提示

  • 生成签名时配置的ContentType必须和前端上传时携带的Content-Type请求头完全一致,否则会返回403权限错误
  • 如果配置了ContentLength参数,前端上传的文件大小必须和该值完全匹配,否则签名校验失败
  • 如果上传时触发CORS错误,需要在S3桶的权限配置中添加对应CORS规则:
[
  {
    "AllowedOrigins": ["https://你的前端业务域名"],
    "AllowedMethods": ["PUT"],
    "AllowedHeaders": ["Content-Type"],
    "ExposeHeaders": []
  }
]
  • 预签名URL本身有权限时效,过期后需要重新向后端请求新的URL

内容的提问来源于stack exchange,提问作者razer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 03:12:15