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

React/JS调用S3预签名URL上传图片报403 Forbidden错误求助

解决React中使用S3预签名URL上传403 Forbidden的问题

核心问题分析

你的Python代码是直接上传二进制文件流,而React中最初用FormData或错误处理请求体的方式,导致请求内容(包括请求体结构、请求头)和预签名URL生成时的验证条件不匹配,S3签名验证失败返回403。

具体解决方案

1. 修正上传请求代码

不要使用FormData,直接将File对象作为请求体发送,同时确保请求头和预签名URL生成时的参数一致:

// on submit:
const options = {
    method: 'put',
    body: img, // 直接传入File对象,无需包装成FormData
    // 仅当预签名URL生成时指定了Content-Type,才添加这个头,值要和文件的type完全一致
    headers: {
        'Content-Type': img.type
    }
};
const res = await fetch(psurl, options);

2. 匹配预签名URL的生成条件

  • 如果生成预签名URL时指定了Content-Type参数(比如Python生成时设置了ContentType),上传请求的Content-Type头必须和这个值完全一致,不能多也不能少。
  • 如果生成预签名URL时没有指定Content-Type,则上传请求不要添加这个头,或者确保头信息和生成时的默认条件匹配。

3. 检查S3存储桶的CORS配置

浏览器环境下的跨域请求需要S3配置正确的CORS规则,允许你的React域名发起PUT请求:

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>https://your-react-app-domain.com</AllowedOrigin> <!-- 替换为你的域名,或用*测试 -->
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader> <!-- 允许所有头,或指定需要的Content-Type等 -->
        <MaxAgeSeconds>3000</MaxAgeSeconds>
    </CORSRule>
</CORSConfiguration>

注意:生产环境不要用*作为AllowedOrigin,仅用于测试场景。

为什么之前的方式失败?

  • FormData会将请求体包装成multipart/form-data格式,包含额外的边界标识和字段信息,这和Python直接上传的二进制流完全不同,S3的签名验证会因为请求体不匹配而拒绝请求。
  • 直接传img["file"]是错误操作,img本身就是File对象,无需额外取file属性。

内容的提问来源于stack exchange,提问作者Ori.B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:25:13