在 Lambda 中使用 multipart/form-data

Working with multipart/form-data in Lambda

我有一个从 AWS API 网关调用的 lambda 函数。

lambda 正在接收图像作为 multipart/form-data 然后 lambda 需要添加一些额外的 headers 并将该图像传递给另一个外部服务也使用 multipart/form-data

现在,我的服务是这样做的:

'use strict'
const AWS = require('aws-sdk');
const https = require('https');
const request = require('request');

exports.handler = (event, context, callback) => {

const options = {
        method: 'POST',
        url: 'https://external-service/image-storage',
        port: 443,
        headers: {
            "Content-Type": "multipart/form-data"
        },
        formData: {
            username: "67a43djte5s4cb54mnasbds23",
            secret: "47938hjfsdhjfdfdfs",
            photo: \ I want to put here the image received in the event
        }
    };

    request(options, function(err, res, body) {
        if (err) console.log(err);
        console.log(body);
    });
}

photo 参数中我尝试输入 event.body 但它不起作用,因为外部服务给了我一个 "invalid request" (我已经尝试过外部服务邮递员,它工作正常)。

所以我认为问题出在 lambda 上。

当我在控制台打印 event.body 的内容时,这是输出:

2020-04-02T13:17:27.478Z    0c03qsrf-78a2-2356-b9b0-0fd76fb367712   INFO    ----------------------------027326659651005153655343
Content-Disposition: form-data; name="image"; filename="MyImage.jpg"
Content-Type: image/jpeg
����JFIF��C...

我是否需要对 body 进行任何额外的转换?

谢谢,

以防万一有人来到这里遇到我昨天遇到的同样问题,最好的方法是遵循 Michael Hausenblas 的建议(请参阅他在我的问题下的评论)并使用 S3 和预签名网址。

但是,由于我的前端存在一些限制,我无法采用这种方法。

最后,我不得不将 API 输入从 multipart/form-data 内容类型替换为 application/json 并将 JSON 对象中以 base64 编码的图像从我的前端发送到我的 lambda。然后从 lambda 构建外部服务的多部分对象:

'use strict'
const AWS = require('aws-sdk');
const request = require('request');

exports.handler = (event, context, callback) => {

    let json_body = JSON.parse(event.body)
    var base64image = json_body.image;
    base64image = base64image.replace('data:image/jpeg;base64,', '');


    request({
        url: 'https://external-service/image-storage',
        method: 'POST',
        formData: {
          'username': '67a43djte5s4cb54mnasbds23',
          'secret': '47938hjfsdhjfdfdfs',
          'image': {
            value: Buffer.from(base64image, 'base64'),
            options: {
              filename: 'photo1.jpg',
              contentType: 'image/jpeg'
            }
          }
        }
      }, function (err,resp,body){
        if(err){
            console.log("Error");
        }else{
            console.log("Response" + body);
        }
    });   
}

正如我所说,我建议采用预签名 url 方法,但我提供了这种替代方法,以防您的前端也有限制。