无服务器框架上传的图片损坏

问题描述 投票:0回答:1

我试图使用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
node.js upload binary serverless-framework
1个回答
0
投票

最简单的方法其实是将Lambda函数完全从循环中抽离出来,用于管理上传过程。S3有一个功能,允许你生成一组临时的凭证,让用户直接将文件上传到S3 bucket。这样做有很多好处,最大的好处是降低了Lambda流二进制数据的成本和每100ms的计费,同时仅仅在支持文件大小,以及错误管理方面,上传的可靠性大大提高。这意味着,用户不再是通过API网关向Lambda用表单上传,而是从前端看,流程更像。

  1. 向API网关端点发出HTTP请求,触发Lambda函数。然后,Lambda函数使用AWS SDK创建一个预签名的URL和具有有效权限的策略(https:/docs.aws.amazon.comAWSJavaScriptSDKlatestAWSS3.html#createPresignedPost-property。). 这些细节会被返回给前端客户机。
  2. 前台按照该预签名URL的要求构造一个表单以及一个文件上传实体。然后将二进制文件直接上传到S3 bucket。
  3. 在这一点上,如果需要的话,前端可以调用另一个Lambda函数(通过API Gateway)来启动新图片的处理,并将其与用户或其他任何需要发生的事情关联起来。你甚至可以通过将S3 put事件直接附加到Lambda函数中来异步处理图片 (https:/www.serverless.comframeworkdocsprovidersawseventss3#s3)

希望对你有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.