如何通过API Gateway向AWS Lambda提交文件并正确解析?
解决Lambda解析前端上传的multipart/form-data文件问题
问题原因
API Gateway在Lambda代理集成模式下,会将multipart/form-data格式的请求体编码为Base64字符串,同时在event中返回isBase64Encoded: true标识,所以直接读取event['body']得到的是编码后的内容,无法直接解析为文件和表单字段。
解决方案步骤
1. 修正前端请求错误
前端fetch请求中不需要设置"Access-Control-Allow-Origin": "*"请求头,这个是服务器端返回的响应头,前端添加会导致无效请求。修改后的前端代码:
var data = new FormData(); data.append('username', 'USER123'); data.append('file', selectedFile); await fetch('myURL/test', { method: 'post', body: data }).then(res => res.json()).then(json => console.log(json)) console.log('Done')
2. Lambda中解析Base64并处理multipart数据
需要先解码Base64字符串,再解析multipart/form-data内容,这里使用multipart库处理(Lambda默认无此库,需通过Lambda层或打包部署添加)。
步骤1:准备依赖(Lambda层方式)
mkdir python pip install multipart -t python/ zip -r multipart-layer.zip python/
在AWS控制台创建Lambda层,上传该zip包并关联到你的Lambda函数。
步骤2:Lambda代码实现
import json import base64 import boto3 from multipart import parse_form_data from io import BytesIO s3 = boto3.client('s3') BUCKET_NAME = '你的S3存储桶名称' def lambda_handler(event, context): # 解码Base64请求体 if event.get('isBase64Encoded', False): body_bytes = base64.b64decode(event['body']) else: body_bytes = event['body'].encode('utf-8') # 解析multipart/form-data environ = { 'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': event['headers']['content-type'], 'CONTENT_LENGTH': str(len(body_bytes)), } form = parse_form_data(environ, BytesIO(body_bytes)) # 获取表单字段与文件 username = form.get('username', [''])[0] file_item = form.get('file', [])[0] file_name = file_item.filename file_content = file_item.file.read() file_size = len(file_content) # 校验文件类型(仅允许.zip) if not file_name.endswith('.zip'): return { 'statusCode': 400, 'body': json.dumps('仅支持上传.zip格式文件') } # 校验文件大小(不超过10MB) MAX_SIZE = 10 * 1024 * 1024 if file_size > MAX_SIZE: return { 'statusCode': 400, 'body': json.dumps('文件大小不能超过10MB') } # 上传至S3 try: s3.put_object( Bucket=BUCKET_NAME, Key=f"{username}/{file_name}", Body=file_content ) return { 'statusCode': 200, 'body': json.dumps('文件上传成功') } except Exception as e: return { 'statusCode': 500, 'body': json.dumps(f'文件上传失败:{str(e)}') }
3. API Gateway配置注意事项
- 确保POST路由使用Lambda代理集成(集成类型选Lambda函数,勾选"使用Lambda代理集成")。
- 在CORS配置中,允许
POST方法和multipart/form-data内容类型,同时返回Access-Control-Allow-Origin: *响应头。
内容的提问来源于stack exchange,提问作者ReactNewbie123
相关产品推荐
相关产品推荐

