AWS Lambda返回S3提取的图片zip包时提示ZipFile不可JSON序列化
报错根因
返回值中直接传入了ZipFile实例,Lambda默认会序列化返回值为JSON格式,ZipFile对象不属于可JSON序列化的类型,因此触发报错。同时你需要返回的是zip文件的二进制内容,而非ZipFile对象本身。
可行实现方案
方案1:直接返回zip二进制(适合压缩包小于6MB的场景)
实现逻辑:
- 关闭ZipFile后重置BytesIO缓冲区指针,读取完整的zip二进制内容
- 将二进制内容转base64编码,适配Lambda/API Gateway的二进制返回规则
- 响应头设置正确的媒体类型,添加base64编码标识
修改后的代码如下:
import io import boto3 import zipfile import base64 def get_zipped_files(files): files = files.split(',') zip_buffer = io.BytesIO() bucket = 'my_bucket' s3 = boto3.client('s3') with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zipper: for file in files: infile_object = s3.get_object(Bucket=bucket, Key=file) infile_content = infile_object['Body'].read() zipper.writestr(file, infile_content) # 重置缓冲区指针到起始位置,读取全部zip二进制内容 zip_buffer.seek(0) zip_bytes = zip_buffer.read() # 转base64编码适配Lambda返回规则 encoded_zip = base64.b64encode(zip_bytes).decode('utf-8') response = { 'statusCode': 200, 'headers': { 'Content-Type': 'application/zip', # 如需浏览器自动触发下载,保留下面的配置 'Content-Disposition': 'attachment; filename="images_pack.zip"' }, 'body': encoded_zip, # 标记body为base64编码的二进制数据,API Gateway会自动解码返回 'isBase64Encoded': True } return response
配置注意事项
- 如果对接了API Gateway,需要在API Gateway的二进制支持配置中,添加
application/zip为支持的二进制媒体类型,避免返回内容被转义损坏。 - Lambda响应payload上限为6MB,压缩包大小超过该阈值时不可用此方案。
方案2:返回S3预签名链接(适合任意大小的压缩包)
如果压缩包体积较大,可采用此方案:
- 生成zip文件后将其上传到S3私有桶
- 生成S3预签名下载链接(可自定义有效期)
- 直接返回下载链接给调用方跳转下载,不受Lambda payload限制
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

