Flask部署至Lambda后上传文件内容与本地运行结果不一致如何解决
问题根因
你遇到的文件损坏是API Gateway默认对请求体做了UTF-8文本转码导致的:
- 你上传的是图片等二进制文件,字节流里存在大量非UTF-8合法编码的字节(比如你本地打印的
\xff、\xd8这类值) - Lambda部署的Flask应用默认前面会配API Gateway做入口,默认配置下API Gateway会把请求体默认识别为文本格式,尝试用UTF-8解码,遇到非法编码的字节就会替换成
\xef\xbf\xbd(也就是你打印结果里反复出现的这个字符),转码后的字节流再传给Lambda侧的Flask,拿到的文件内容已经被篡改,所以存到S3就损坏了。
修复方案
你可以按以下步骤配置解决:
第一步:修改API Gateway配置,开启二进制支持
- 进入你对应Lambda的API Gateway控制台,找到
设置菜单,在二进制媒体类型里添加你要支持的上传类型,比如如果是上传所有类型就填*/*,如果只传图片就填image/*,保存后重新部署API。 - 如果你用的是Serverless Framework或者SAM这类工具部署,可以直接在配置文件里声明二进制媒体类型,示例(SAM模板配置):
Globals: Api: BinaryMediaTypes: - "*/*"
第二步:确保Flask侧直接读取原始二进制字节
确认你后续写入S3的逻辑是直接读取ff.read()的原始字节,不要做任何编码转换操作,示例写入S3的正确代码:
import boto3 s3 = boto3.client('s3') @app.route('/upload_participant_data', methods=['POST']) def upload_participant_data(): ff = request.files['file'] ff.seek(0) # 直接读原始字节上传,不要做decode/encode操作 file_content = ff.read() s3.put_object( Bucket='你的存储桶名', Key='保存的文件名', Body=file_content, ContentType=ff.content_type ) return '上传成功'
第三步:验证部署
重新发布Lambda和API Gateway配置后再测试上传,文件字节就不会被篡改,存到S3的文件可以正常打开。
内容的提问来源于stack exchange,提问作者Gnaaaa
相关产品推荐
相关产品推荐

