Postman上传图片至Lambda再转存S3时遇文件类型不支持问题求助
问题解决:Lambda处理表单上传图片至S3后文件格式不支持
问题描述
通过Postman表单上传图片,经Lambda函数接收后存储到S3,已配置Lambda与S3的访问权限,但文件名显示正常,下载时提示“filetype not supported”。
代码问题分析
原代码中POST请求处理存在以下核心问题:
- 手动通过
body.split('image/jpeg\r\n\r\n')[1]拆分请求体,硬编码方式仅适配特定格式的multipart请求,一旦请求边界符、Content-Type稍有变化,就会导致存储的文件内容损坏(包含多余HTTP边界信息或缺失文件数据),最终无法被识别格式。 - 固定设置
ContentType='image/jpeg',无法兼容png、gif等其他图片格式。 - 未正确解析multipart/form-data类型的表单数据,直接操作原始body存在兼容性风险。
修复后的代码
import json import boto3 import base64 import cgi import io s3_client = boto3.client('s3') BUCKET_NAME = 'u' last_value = None def lambda_handler(event, context): global last_value print(json.dumps(event)) # 处理API Gateway请求 if 'httpMethod' in event: if event['httpMethod'] == 'POST': try: headers = event.get('headers', {}) body = event.get('body', '') # 解码base64编码的请求体 if event.get('isBase64Encoded', False): body = base64.b64decode(body) # 校验请求类型为multipart/form-data content_type = headers.get('Content-Type', '') if not content_type.startswith('multipart/form-data'): raise ValueError("仅支持multipart/form-data类型请求") # 解析multipart表单数据 form_data = cgi.FieldStorage( fp=io.BytesIO(body), headers=headers, environ={'REQUEST_METHOD': 'POST'} ) # 获取表单中的文件字段(Postman中表单键名需为'file') file_item = form_data.get('file') if not file_item: raise ValueError("表单中缺少'file'字段") file_name = file_item.filename file_content = file_item.file.read() content_type = file_item.type # 上传至S3 s3_client.put_object( Bucket=BUCKET_NAME, Key=file_name, Body=file_content, ContentType=content_type ) last_value = file_name print('已上传文件:', last_value) return { 'statusCode': 200, 'body': json.dumps(f'文件上传成功: {last_value}') } except Exception as e: return { 'statusCode': 500, 'body': json.dumps(f'上传失败: {str(e)}') } elif event['httpMethod'] == 'GET': try: # 获取最近上传的文件 file_name = last_value if not file_name: raise ValueError("暂无已上传文件") s3_response = s3_client.get_object(Bucket=BUCKET_NAME, Key=file_name) image_data = s3_response['Body'].read() content_type = s3_response['ContentType'] return { 'statusCode': 200, 'isBase64Encoded': True, 'headers': { 'Content-Type': content_type }, 'body': base64.b64encode(image_data).decode('utf-8') } except Exception as e: return { 'statusCode': 500, 'body': json.dumps(f'获取图片失败: {str(e)}') } # 处理S3事件 elif 'Records' in event and event['Records'][0]['eventSource'] == 'aws:s3': for record in event['Records']: bucket_name = record['s3']['bucket']['name'] object_key = record['s3']['object']['key'] print(f"文件已上传至存储桶: {bucket_name}, 路径: {object_key}") return { 'statusCode': 200, 'body': json.dumps('S3事件处理完成') }
关键修复点
- 使用Python内置
cgi.FieldStorage解析multipart表单,正确提取文件二进制内容、文件名和原生Content-Type。 - 动态设置S3对象的Content-Type,适配所有图片格式。
- 直接使用解析后的纯净文件内容上传,避免手动拆分请求体导致的内容损坏。
Postman配置注意事项
- 请求方法选POST,请求体选
form-data。 - 添加键名为
file的字段,类型选File,选择本地图片文件上传。 - 无需手动添加
file-name头,解析器会自动从表单中提取文件名。
内容的提问来源于stack exchange,提问作者Ashish Nagmoti
相关产品推荐
相关产品推荐

