【问题标题】:Serverless framework uploaded image is corrupt无服务器框架上传的图像已损坏
【发布时间】:2020-08-22 15:26:43
【问题描述】:

我正在尝试使用可以接受二进制输入并将数据存储在 S3 中的无服务器框架编写文件上传服务。

问题是文件最终在 S3 存储桶中损坏。文本文件可以通过,但我的测试图像没有。

这是我目前的代码:

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 时,AWS 自动为您创建了一个 API 网关。转到 API Gateway 设置并添加 */* 以被视为二进制文件。那应该可以解决您的问题。如果没有,请在不设置任何内容类型的情况下执行您的 PUT 请求。 (除了*/*) Obs:@gareth-mccumskey 回复可能是正确的方法,但这是针对具体问题的解决方案。

标签: node.js upload binary serverless-framework


【解决方案1】:

最简单的方法是让 Lambda 函数完全脱离循环以管理上传过程。 S3 具有允许您生成一组临时凭证以允许用户将文件直接上传到 S3 存储桶的功能。这有很多好处,最大的好处是降低了 Lambda 流二进制数据和每 100 毫秒计费的成本,以及仅支持文件大小和错误管理的更可靠的上传。这意味着不是用户通过 API Gateway 将表单上传到 Lambda,而是来自前端的过程看起来更像:

  1. 向触发 Lambda 函数的 API Gateway 端点发出 HTTP 请求。然后,Lambda 函数使用 AWS 开发工具包创建具有有效权限 (https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createPresignedPost-property) 的预签名 URL 和策略。然后将这些详细信息返回给前端客户端
  2. 前端根据该预签名 URL 的要求以及文件上传实体构造一个表单。然后二进制文件将直接上传到 S3 存储桶。
  3. 此时,如果需要,前端可以调用另一个 Lambda 函数(通过 API 网关)来启动新图像的处理并将其与用户相关联或此时需要发生的任何其他事情。您甚至可以通过将 S3 put 事件直接附加到 Lambda 函数来异步处理图像 (https://www.serverless.com/framework/docs/providers/aws/events/s3/#s3)

希望对您有所帮助。

【讨论】:

  • 我明确不允许这样做。除了按原样提供文件之外,我还想在某些情况下对其进行操作。如果文件是图像,则应调整大小并以这种方式存储。客户端应该只上传二进制文件。
  • 将图像添加到存储桶后,您仍然可以对其进行操作。您创建两个存储桶。一个用于原始图像,一个用于更改。将图像插入其中时,它会自动触发 Lambda 函数的执行以开始处理。然后,该 Lambda 将新创建的图像保存在第二个存储桶中。上传到 S3 也比任何其他可能的上传方法好得多,即使您有一个完整的 EC2 实例来接收图像。说服你需要允许的人。
猜你喜欢
  • 2021-08-21
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 2019-10-02
  • 1970-01-01
  • 2019-05-06
  • 2012-08-03
相关资源
最近更新 更多