FastAPI+Lambda+API Gateway部署后上传Excel文件损坏问题
解决FastAPI+Mangum部署Lambda/API Gateway后Excel文件损坏问题
核心问题根源
API Gateway默认会对非文本类型的请求/响应做字符编码转换或Base64处理,而.xlsx本质是ZIP压缩包,二进制数据一旦被篡改就会触发zipfile.BadZipFile错误。结合Mangum的适配逻辑,需要从配置和代码层面同步调整。
分步解决方案
1. 配置API Gateway二进制媒体类型
- 登录API Gateway控制台,进入目标API的Settings页面,在Binary Media Types中添加以下两种类型:
multipart/form-data(处理文件上传的表单类型)application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(xlsx文件的MIME类型)
- 若用SAM/CloudFormation部署,需在
AWS::ApiGateway::RestApi资源中显式配置:Resources: MyApi: Type: AWS::ApiGateway::RestApi Properties: Name: MyExcelUploadApi BinaryMediaTypes: - "multipart/form-data" - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
2. 调整Mangum初始化配置
Mangum需要明确告知API Gateway的Base64编码逻辑,避免二进制数据被错误转码:
from mangum import Mangum # 初始化时开启Base64编码支持 handler = Mangum(app, api_gateway_base64_encoded=True)
3. 确保文件上传时读取原始二进制数据
在FastAPI的上传接口中,直接读取文件的二进制内容,不要进行字符串解码:
from fastapi import FastAPI, UploadFile, File import boto3 app = FastAPI() s3 = boto3.client("s3") @app.post("/upload-excel") async def upload_excel(file: UploadFile = File(...)): # 直接读取二进制字节流,跳过字符串解码步骤 file_bytes = await file.read() # 上传到S3时指定正确的Content-Type s3.put_object( Bucket="your-bucket-name", Key=f"uploads/{file.filename}", Body=file_bytes, ContentType=file.content_type ) return {"status": "success"}
4. 验证文件完整性
- 上传完成后,从S3控制台下载文件,对比本地原文件的大小:若大小不一致,说明传输过程中数据被篡改。
- 用终端命令验证文件是否为有效ZIP包:
若输出"No errors detected",则文件正常;否则需检查编码链路。unzip -t your-uploaded-file.xlsx
5. 排查API Gateway阶段配置
部分场景下,全局Binary Media Types设置不会自动同步到部署阶段:
- 进入API的Stages页面,选择目标阶段,进入Settings,确认Binary Media Types已包含所需类型。
内容的提问来源于stack exchange,提问作者frenchytheasian
相关产品推荐
相关产品推荐

