使用无服务器处理 multipart/form-data?

Handle multipart/form-data with Serverless?

如何使用无服务器框架处理 multipart/form-data? v.0.5.6

刚试过这个:

"requestTemplates": {
        "multipart/form-data": {
          "httpMethod": "$context.httpMethod",
          "body": "$input.json('$')",
          "queryParams": "$input.params().querystring",
          "headerParams": "$input.params().header",
          "headerParamNames": "$input.params().header.keySet()",
          "contentTypeValue": "$input.params().header.get('Content-Type')"
        },
        "application/json": {
          "httpMethod": "$context.httpMethod",
          "body": "$input.json('$')",
          "queryParams": "$input.params().querystring",
          "headerParams": "$input.params().header",
          "headerParamNames": "$input.params().header.keySet()",
          "contentTypeValue": "$input.params().header.get('Content-Type')"
        }
      }

action.js:

export function respond(event, cb) {

    var form = new formidable.IncomingForm();
    form.parse(event, function(err, fields, files) {
        if (err == null) {
            var response = {
                status: "true",
                data: fields,
                error: []
            };
            return cb(null, response);
        } else {
            console.log(err);
            return cb(null, ApiErrors.errors(402, err['message'] + fields));
        }
    });



}

但出现错误:errorMessage = "Cannot read property 'content-length' of undefined";

嗯,我不能把它变成multipart/form-data,所以我使用了base64字符串。

action.js:

export function respond(event, cb) {
    //console.log('Received event:', JSON.stringify(event, null, 2));

    var key = new Date().toISOString().substr(0, 10) + '/' + String(Date.now());
    var contentType = event.body["data"].substr(0, event.body["data"].indexOf(';'));

    if (!contentType.match(/(\.|\/)(gif|jpe?g|png)$/i)) {
        return cb(null, 'invalid content type, gif, jpg, and png supported');
    }
    var data = new Buffer(event.body["data"].replace(/^image\/\w+;base64,/, ''),'base64');

    var params = {
        Bucket: 'your-bucket',
        Key: key,
        Body: data,
        ContentEncoding: 'base64',
        ContentType: contentType,
        ACL: 'public-read'
    };
    s3.upload(params, function (err, data) {
        if (err) {
            console.log(err);
            return cb(null, ApiErrors.errors(402, err['message']));
        } else {
            var response = {
                status: "true",
                data: {
                    url: urlPrefix + key
                },
                error: []
            };
            return cb(null, response);
        }
    });

}

请求模板:

"requestTemplates": {
        "application/json": {
          "httpMethod": "$context.httpMethod",
          "body": "$input.json('$')",
          "header": "$input.params().header.get($header)",
          "headerParam": "$input.params().header.keySet()",
          "contentType": "$input.params().header.get('Content-Type')"
        }
      },

我已经使用 serverless by emulating http.ClientRequest and using a form parser tool like formidable 了。

我正在使用 lambda-proxy 进行 API 网关事件配置。

const Stream      = require('stream').Readable;
const Formidable  = require('formidable');

module.exports.upload = ( e, ctx, cb ) => {
    let form = new Formidable.IncomingForm();

    let stream = new Stream();
    stream.push( e.body );
    stream.push( null );

    // NOTE: You'll likely want to toLowerCase() at least 'Content-Type' header key
    stream.headers = e.headers;

    form.parse( stream, (err, fields, files) => {
        // Work with your parsed form results here.
    });
}