如何在Lambda中从API Gateway的文件上传请求获取文件名?
解决Lambda中解析multipart/form-data获取文件名并上传S3的问题
你之前的问题核心在于:event['body']是multipart/form-data格式的原始文本,并非JSON结构,所以用json.loads解析必然失败。以下是具体解决步骤和代码:
1. 用标准库cgi解析multipart内容
Python内置的cgi模块可以直接解析multipart/form-data格式的数据,无需额外安装依赖,适配Lambda运行环境。
2. 完整Lambda代码示例
import sys import os import boto3 import cgi import json from io import BytesIO # 初始化S3客户端,替换为你的存储桶名称 s3 = boto3.client('s3') TARGET_BUCKET = 'your-target-bucket-name' def lambda_handler(event, context): # 获取原始请求体 raw_body = event['body'] # 若API Gateway开启了Base64编码,需先解码(根据实际情况调整) # if event.get('isBase64Encoded', False): # import base64 # raw_body = base64.b64decode(raw_body) # 将文本转为类文件对象,供cgi模块解析 body_file = BytesIO(raw_body.encode('utf-8')) # 解析multipart表单数据 form = cgi.FieldStorage( fp=body_file, headers={'Content-Type': event['headers']['Content-Type']}, environ={'REQUEST_METHOD': 'POST'} ) # 获取表单中的文件字段(对应前端表单name="file") file_field = form['file'] # 提取文件名 filename = file_field.filename # 读取文件内容 file_content = file_field.file.read() # 上传文件到S3 try: s3.put_object( Bucket=TARGET_BUCKET, Key=filename, # 可自定义S3对象键,比如加上前缀 Body=file_content ) return { 'statusCode': 200, 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, 'body': json.dumps({ 'msg': '文件上传成功', 'filename': filename, 'bucket': TARGET_BUCKET }), 'isBase64Encoded': False } except Exception as e: return { 'statusCode': 500, 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, 'body': json.dumps({'error': str(e)}), 'isBase64Encoded': False }
3. 关键配置注意事项
- API Gateway需保持请求体原始传递,集成请求中不要设置将body转为JSON的规则。
- 给Lambda执行角色添加S3上传权限(
s3:PutObject),避免权限不足报错。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

