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

编写Lambda函数上传文件至S3桶遇KeyError问题求助

错误原因分析
  1. event结构访问错误:Lambda的event是字典类型,不是对象,用event.body会触发AttributeError;改成event['body']后报KeyError,说明触发Lambda的请求(比如API Gateway调用、控制台测试)传入的event里根本没有body字段,或者字段结构不符合预期。
  2. S3操作逻辑错误:s3.put_object()是上传文件到S3的方法,它的返回结果里没有Body字段——这个方法只返回上传成功的元数据(比如ETag),你试图读取response['Body']属于逻辑错误。
  3. 返回值逻辑错误:上传完成后不需要返回文件内容,应该返回上传成功的标识或文件的访问地址。
修复后的代码(以API Gateway触发上传为例)

假设你通过API Gateway的POST请求上传JPG图片,且API Gateway已配置支持二进制媒体类型,修复后的代码如下:

import base64
import boto3
import uuid

s3 = boto3.client('s3')
BUCKET_NAME = 'your-s3-bucket-name'  # 替换成你的S3桶名

def lambda_handler(event, context):
    # 处理请求中的文件内容
    try:
        # 从API Gateway的event中获取base64编码的图片数据
        encoded_image = event['body']
        # 解码为二进制格式,用于上传S3
        image_data = base64.b64decode(encoded_image)
    except KeyError:
        return {
            'statusCode': 400,
            'headers': {
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token",
                "Access-Control-Allow-Methods": "*",
                "Access-Control-Allow-Credentials": "true"
            },
            'body': '请求缺少文件内容(body字段)'
        }
    except Exception as e:
        return {
            'statusCode': 400,
            'headers': {
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token",
                "Access-Control-Allow-Methods": "*",
                "Access-Control-Allow-Credentials": "true"
            },
            'body': f'文件解码失败: {str(e)}'
        }

    # 生成唯一文件名,避免重复覆盖
    file_key = f"{str(uuid.uuid4())}.jpg"

    try:
        # 上传文件到S3
        s3.put_object(
            Bucket=BUCKET_NAME,
            Key=file_key,
            Body=image_data,
            ContentType='image/jpg'  # 指定文件类型,帮助S3正确识别
        )

        # 生成文件访问地址(前提是桶配置了公开可读,或可替换为预签名URL)
        file_url = f"https://{BUCKET_NAME}.s3.amazonaws.com/{file_key}"

        return {
            'statusCode': 200,
            'headers': {
                "Content-Type": "application/json",
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token",
                "Access-Control-Allow-Methods": "*",
                "Access-Control-Allow-Credentials": "true"
            },
            'body': f'文件上传成功!访问地址: {file_url}'
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'headers': {
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token",
                "Access-Control-Allow-Methods": "*",
                "Access-Control-Allow-Credentials": "true"
            },
            'body': f'上传失败: {str(e)}'
        }
关键注意事项
  • API Gateway配置:必须在API Gateway的设置中添加image/jpg到二进制媒体类型列表,否则API Gateway会把二进制图片转成字符串,导致解码失败。
  • Lambda权限:确保Lambda的执行角色拥有s3:PutObject权限,允许操作目标S3桶。
  • 控制台测试格式:如果直接在Lambda控制台测试,需要构造符合API Gateway格式的event,示例:
    {
      "body": "你的JPG图片base64编码内容",
      "isBase64Encoded": true
    }
    
  • 文件类型校验:如果需要限制上传文件类型,可以在代码中添加对文件头或请求Content-Type的校验,避免非JPG文件上传。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:10:23