测试AWS Lambda生成S3预签名URL时遇JSON解析错误求助
问题排查与修复方案
1. 核心错误:JSON.parse失败的根源
你遇到的"[object Object]" is not valid JSON错误,问题出在测试用API模板的body格式不符合Lambda预期:
- 当Lambda被API Gateway触发时,
event.body会是JSON字符串(对应前端发送的JSON请求体);但你提供的测试模板里,body是直接的JS对象,且isBase64Encoded设为true。 - 执行
JSON.parse(event.body)时,对象会被强制转为字符串"[object Object]",自然无法解析为合法JSON。
修正测试模板
两种修复方式任选其一:
方式一:关闭base64编码,使用JSON字符串作为body
{ // ... 其他字段保持不变 "body": "{\"fileName\": \"value1.mp4\", \"fileType\": \"video/mp4\"}", "isBase64Encoded": false }
方式二:保持base64编码,将JSON对象转为base64字符串
把{"fileName": "value1.mp4", "fileType": "video/mp4"}转为base64编码后填入body:
{ // ... 其他字段保持不变 "body": "eyJmaWxlTmFtZSI6ICJ2YWx1ZTEubXA0IiwgImZpbGVUeXBlIjogInZpZGVvL21wNCJ9", "isBase64Encoded": true }
2. Lambda代码的其他致命错误
即使解决了JSON解析问题,你的代码仍会报错,因为S3预签名URL的生成逻辑完全错误:
- 错误导入了
ListBucketsCommand,实际需要PutObjectCommand; @aws-sdk/client-s3的S3Client没有静态方法getSignedUrl,需使用@aws-sdk/s3-request-presigner包的getSignedUrl函数。
修正后的Lambda代码
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; const bucketName = "temp-videobucket-hls"; // 创建S3客户端实例,替换为你的AWS区域(比如us-east-1) const s3Client = new S3Client({ region: "你的AWS区域" }); export const handler = async (event) => { let body; // 兼容测试和API Gateway的不同body格式 try { body = typeof event.body === 'string' ? JSON.parse(event.body) : event.body; } catch (parseErr) { console.error('Failed to parse request body', parseErr); return { statusCode: 400, body: JSON.stringify({ error: 'Invalid request body' }) }; } const { fileName, fileType } = body; if (!fileName || !fileType) { return { statusCode: 400, body: JSON.stringify({ error: 'Missing fileName or fileType' }) }; } const params = { Bucket: bucketName, Key: fileName, Expires: 60, ContentType: fileType }; try { // 使用PutObjectCommand和getSignedUrl生成预签名URL const uploadUrl = await getSignedUrl(s3Client, new PutObjectCommand(params), { expiresIn: 60 }); return { statusCode: 200, body: JSON.stringify({ uploadUrl }) }; } catch (err) { console.error('Error generating pre-signed URL', err); return { statusCode: 500, body: JSON.stringify({ error: 'Failed to generate pre-signed URL' }) }; } };
代码修正说明
- 新增
S3Client实例化,需指定你的AWS区域; - 替换为正确的命令和预签名函数;
- 增加body解析容错逻辑,兼容测试时的对象格式和实际触发时的字符串格式;
- 增加参数校验,避免因缺少字段导致后续错误。
内容的提问来源于stack exchange,提问作者A_beginner
相关产品推荐
相关产品推荐

