使用Serverless+AWS Lambda上传文件到S3后文件损坏如何解决?
解决方案
1. 修正请求Body的解码逻辑
API Gateway开启二进制支持后,默认会将二进制请求体以Base64编码的形式传递给Lambda,你当前直接将入参data按binary编码转Buffer的逻辑存在问题,需要先判断是否为Base64编码再解码:
const rawBody = event.isBase64Encoded ? Buffer.from(event.body, 'base64') : Buffer.from(event.body, 'binary');
2. 正确解析multipart/form-data格式
不能直接将完整请求体传入S3,需要先拆分multipart表单中的文件字段,推荐使用成熟的解析库处理,避免手动拆分出错:
- 首先安装解析依赖:
npm i parse-multipart - 解析示例代码:
import * as multipart from 'parse-multipart'; // 从请求头获取multipart的分隔符 const contentType = event.headers['content-type'] || event.headers['Content-Type']; const boundary = multipart.getBoundary(contentType); // 解析得到所有表单字段,文件字段会存在data属性中 const formParts = multipart.Parse(rawBody, boundary); // 取对应表单字段的文件数据,此处替换为你实际的表单文件字段名即可 const uploadFile = formParts.find(item => item.name === 'file');
3. 修正S3上传逻辑
直接使用解析出来的文件Buffer上传即可,无需二次编码转换:
await this.client.putObject({ Bucket: s3bucket, Key: s3path, Body: uploadFile.data, ContentType: uploadFile.type }).promise();
4. 确认API Gateway配置生效
如果你使用的是REST API,修改binaryMediaTypes后需要重新部署API Gateway阶段才会生效;如果使用的是HTTP API,需要在serverless.yml中补充以下配置:
provider: httpApi: payload: '2.0' binaryMediaTypes: - '*/*'
修改配置后建议重新部署整套栈,避免旧配置缓存导致不生效。
内容的提问来源于stack exchange,提问作者Jérémy Llanta
相关产品推荐
相关产品推荐

