我是Lambda和API网关的新手。我已经使用此服务做了简单的事情,但是现在我有一个要求用户可以上传Excel文件的要求。上传过程只需触发与lambda函数集成的API网关端点。我不想保存文件,我只想将文件数据作为csv/json格式发送到我的lambda函数(nodejs代码(,然后处理/变换/坚持数据。有人知道该怎么做吗?我已经尝试了几件事,但我真的迷路了。
正如我在问题中所说的那样,我不需要保存文件。我将文件数据通过API网关(代理模式(传递到lambda函数,使用parse-multipart
解析数据,然后使用node-xlsx
解析零件缓冲区以触及可读数据。
您可以将文件转换为Buffer
对象,然后将上传(使用fs
也可以工作(将其转换为API。一旦作为参数的一部分收到LAMBDA,您就可以再次将其转换回CSV,然后将其写下/上传到S3/转换为base64并存储在DB中,无论您的体系结构建议哪种方法。
我不会将API网关带入方程式。您上传到API网关的大小限制。
浏览器-CloudFront -S3 Bucket(触发(-Lambda
如果要保护端点以上传到S3,则可以使用signedurl保护端点。
浏览器-CloudFront -Apigw -Lambda(返回签名( - 上传 使用上述步骤
上传文件后,您可以从lambda读取S3对象/文件并从那里进行处理。
在我的项目中,这就是我的方式:
- 前端将文件转换为base64字符串。
- base64字符串随后包含在JSON有效载荷中。
- JSON有效载荷已发送到API网关
POST
端点。 - API网关触发一个Lambda处理程序,然后将base64字符串转换为nodejs
Buffer
对象。 -
Buffer
对象传递到返回上传对象的S3键的aws-sdk
'SS3.upload()
方法。 - 然后,我会将此S3键保存到数据库中。
请注意,此方法对文件大小有限制(API网关限制(,因此我的前端检查此限制之前,请先发送到API。
如果要越过API网关的限制,则必须直接从客户端或前端上传到S3。
我被困在此任务上一段时间,这是最终的工作解决方案
-
通过API网关创建API端点。
-
创建一个路由,该路由将触发负责上传/获取文件的lambda函数。
-
现在转到您的 aws console - > API网关 - > XYZ API (您刚创建的API( - >设置在此处输入图像描述
-
向下滚动到页面末尾,转到二进制媒体类型并写入
*/*
。 -
转到资源在您的API中,选择您的路线,单击任何方法,选择方法响应,然后最后一步是在响应模型中设置内容类型
application/vnd.openxmlformats-offedocument.spreadsheetml.sheet
在这一点上,您已经配置了初始设置,现在该通过lambda函数将XLSX文件保存和检索XLSX文件。
上传文件代码
以二进制格式发送文件(用于测试目的使用Postman(。确保您使用的lambda功能具有所需的权限。
const s3 = new AWS.S3();
await s3.createBucket({ Bucket: "Your_Bucket_Name"}).promise();
const saveFileResponse = await s3
.putObject({
Bucket: "Your_Bucket_Name",
Body: Buffer.from(event.body, "base64"),
Key: "test-file.xlsx",
ContentType: event.headers["Content-Type"]
})
.promise();
return {
statusCode: 200,
body: JSON.stringify("New file stored successfully"),
};
获取文件代码
const s3Object = await s3
.getObject({
Bucket: "Your_Bucket_Name",
Key: "test-file.xlsx",
})
.promise();
const responseBody = s3Object.Body.toString("base64");
return {
statusCode: 200,
body: responseBody,
headers: {
"Content-Type": s3Object.ContentType,
"Access-Control-Allow-Origin": "*",
"Content-Disposition": "attachment; filename=test-file.xlsx",
},
isBase64Encoded: true,
};
希望这会有所帮助:(