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

React使用Python Lambda生成的S3预签名URL上传图片遇403错误

问题排查方案

关于你提到的公共访问和ACL疑问

关闭S3公共访问完全不影响预签名URL的使用,无需调整公共访问配置。ACL默认设置private即可,不需要开启public-read,预签名URL的权限完全来源于生成它的身份(也就是Lambda的执行角色)的权限,和桶的公开权限无关。


具体排查步骤

  • 第一步:检查Lambda执行角色的IAM权限
    Lambda使用的执行角色必须配置s3:PutObject权限,且资源路径要正确指向桶内对象,参考策略示例:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "s3:PutObject",
                "Resource": "arn:aws:s3:::你的S3桶名称/*"
            }
        ]
    }
    

    注意资源路径末尾必须加/*,仅写桶ARN会导致权限不生效。

  • 第二步:检查S3桶的CORS配置
    你的报错类型为cors,大概率是CORS规则配置错误,S3桶需要放开你前端域名的PUT请求权限,参考配置:

    [
        {
            "AllowedHeaders": ["*"],
            "AllowedMethods": ["PUT", "GET"],
            "AllowedOrigins": ["你的前端域名,开发环境可填http://localhost:3000"],
            "ExposeHeaders": ["ETag"]
        }
    ]
    
  • 第三步:校验Content-Type是否完全一致
    生成预签名URL时传入的ContentType参数,必须和前端PUT请求头里的Content-Type完全一致,包括大小写、额外参数,比如后端传的是image/jpeg就不能在前端写成image/JPEG,也不能多带charset=utf-8这类额外参数,建议前后端都打印日志确认两个值完全匹配。

  • 第四步:检查S3桶的额外限制配置
    如果你的桶开了服务端加密(SSE),生成预签名URL时需要补充对应的加密参数,比如使用SSE-S3加密的话,要在generate_presigned_url的参数里添加"ServerSideEncryption": "AES256";如果桶配置了自定义桶策略,检查是否存在限制Lambda角色访问、要求特定请求头的规则。

  • 第五步:确认区域和签名配置
    boto3初始化S3客户端时要指定和桶一致的区域,否则会出现签名不匹配的问题,示例:

    s3_client = boto3.client("s3", region_name="你的桶所在区域,比如ap-northeast-1")
    

    另外不要缓存预签名URL太久,你配置的300秒有效期是合理的,拿到URL后要尽快发起请求。

  • 快速验证方法
    你可以先在本地用AWS CLI生成预签名URL,用curl测试能否上传,如果测试成功说明IAM和桶配置没问题,问题出在前后端参数匹配环节;如果测试失败就优先排查IAM和桶配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:42:03