如何解决AWS Lambda中用Python Requests解析Multipart/Form-Data的错误
解决AWS Lambda Function URL解析multipart/form-data的问题
问题分析
你遇到的ImproperBodyPartContentException: content does not contain CR-LF-CR-LF错误,核心原因是:
- AWS Lambda Function URL默认会将
multipart/form-data类型请求的body进行Base64编码,直接对event['body']调用encode()会导致MultipartDecoder无法识别正确的分隔符格式 - 请求头的键存在大小写差异(如
Content-Type和content-type),直接按固定键名获取可能失败
修正后的Python Lambda代码
以下代码仅依赖requests和requests-toolbelt库,实现接收字符串字段(name、date、text)及图片文件,并将图片保存为PNG格式到Lambda的/tmp目录:
import json import base64 import requests from requests_toolbelt.multipart import decoder def lambda_handler(event, context): try: # 处理Base64编码的请求体 body = event['body'] if event.get('isBase64Encoded', False): body = base64.b64decode(body) # 兼容大小写的请求头获取 content_type = None for key, value in event['headers'].items(): if key.lower() == 'content-type': content_type = value break if not content_type: return { 'statusCode': 400, 'body': json.dumps({'error': 'Missing Content-Type header'}) } # 解析multipart/form-data data = decoder.MultipartDecoder(body, content_type) # 存储表单字段和文件内容 form_data = {} image_content = None for part in data.parts: # 解析Content-Disposition头 disp_header = part.headers[b'content-disposition'].decode('utf-8') # 提取字段名 name_start = disp_header.find('name="') + 6 name_end = disp_header.find('"', name_start) field_name = disp_header[name_start:name_end] # 判断是否为文件字段 if 'filename=' in disp_header: image_content = part.content else: # 解析字符串字段 form_data[field_name] = part.content.decode('utf-8') # 验证必要字段 required_fields = ['name', 'date', 'text'] missing_fields = [f for f in required_fields if f not in form_data] if missing_fields: return { 'statusCode': 400, 'body': json.dumps({'error': f'Missing required fields: {", ".join(missing_fields)}'}) } # 将图片保存为PNG到/tmp目录 if image_content: save_path = '/tmp/uploaded_image.png' with open(save_path, 'wb') as f: f.write(image_content) print(f'图片已保存到: {save_path}') else: return { 'statusCode': 400, 'body': json.dumps({'error': 'Missing image file'}) } # 返回成功响应 return { 'statusCode': 200, 'body': json.dumps({ 'message': '请求处理成功', 'received_data': form_data, 'image_saved': True }) } except Exception as e: return { 'statusCode': 500, 'body': json.dumps({'error': str(e)}) }
关键修改点说明
- Base64解码处理:通过
event['isBase64Encoded']判断并解码请求体,这是解决核心错误的关键 - 大小写兼容的请求头获取:遍历headers并忽略键的大小写,避免因请求头键名大小写不一致导致的错误
- 通用字段解析逻辑:不再硬编码字段判断,而是从Content-Disposition头中提取字段名,适配不同的表单字段
- 强制PNG格式保存:直接将图片内容写入
/tmp/uploaded_image.png,确保输出为PNG格式 - 异常处理与参数校验:添加必要的字段校验和异常捕获,返回更友好的错误信息
- 前端请求优化提示:你的React前端代码无需修改,但注意axios会自动处理
multipart/form-data的边界符,不需要手动设置Content-Type(手动设置可能会丢失边界符信息),可以修改为:export async function postFormData(url, form) { const response = await axios.post(url, form); return response.data; }
内容的提问来源于stack exchange,提问作者Asif Alam
相关产品推荐
相关产品推荐

