我试图使用serverless框架编写一个文件上传服务,可以接受二进制输入并将数据存储在S3中。
问题是文件在S3 bucket中最终会损坏。文本文件确实可以通过,但我的测试图片却不能。
这是我目前的代码。
const serverless = require('serverless-http');
const express = require('express');
const crypto = require("crypto")
const AWS = require('aws-sdk');
const app = express();
const s3 = new AWS.S3();
app.use(function(req, res, next) {
var chunks = [];
req.on('data', function(chunk) { chunks.push(chunk); });
req.on('end', function() {
req.rawBody = Buffer.concat(chunks);
next();
});
});
app.put('/v1/upload', async (req, res, cb) => {
let hash = crypto.createHash("sha256").update(req.rawBody).digest("hex");
console.log(req.rawBody.length);
... s3 stuff here
我可以在控制台看到文件大小是错误的 2540872。真正的大小是1395559.我用curl来测试上传。
curl -v -X PUT -H "Content-Type: application/octet-stream" --data-binary @test/image.png http://localhost:3000/prod/v1/upload
最简单的方法其实是将Lambda函数完全从循环中抽离出来,用于管理上传过程。S3有一个功能,允许你生成一组临时的凭证,让用户直接将文件上传到S3 bucket。这样做有很多好处,最大的好处是降低了Lambda流二进制数据的成本和每100ms的计费,同时仅仅在支持文件大小,以及错误管理方面,上传的可靠性大大提高。这意味着,用户不再是通过API网关向Lambda用表单上传,而是从前端看,流程更像。
希望对你有所帮助。