aws-sdk s3上传方法破坏图像文件

时间:2018-08-05 16:10:28

标签: amazon-web-services amazon-s3 file-upload aws-lambda aws-sdk

这里的每个人都是我的问题。 我用以下代码编写了一个AWS Lambda:

const AWS = require('aws-sdk');
const S3 = new AWS.S3();

function getValueIgnoringKeyCase(object, key) {
    const foundKey = Object
        .keys(object)
        .find(currentKey => currentKey.toLocaleLowerCase() === key.toLowerCase());
    return object[foundKey];
}

function getBoundary(event) {
    return getValueIgnoringKeyCase(event.headers, 'Content-Type').split('=')[1];
}


module.exports.hello = (event, context, callback) => {
    const boundary = getBoundary(event);
    const result = {};
    event.body
        .split(boundary)
        .forEach(item => {
            if (/filename=".+"/g.test(item)) {
                result[item.match(/name=".+";/g)[0].slice(6, -2)] = {
                    type: 'file',
                    filename: item.match(/filename=".+"/g)[0].slice(10, -1),
                    contentType: item.match(/Content-Type:\s.+/g)[0].slice(14),
                    content: item.slice(item.search(/Content-Type:\s.+/g) + item.match(/Content-Type:\s.+/g)[0].length + 4, -4),
                };
            } else if (/name=".+"/g.test(item)){
                result[item.match(/name=".+"/g)[0].slice(6, -1)] = item.slice(item.search(/name=".+"/g) + item.match(/name=".+"/g)[0].length + 4, -4);
            }
        });

    const response = {
        statusCode: 200,
        body: JSON.stringify(result),
    };

    Promise.all(Object.keys(result)
        .filter(item => result[item].type === 'file')
        .map(item => (new Promise((resolve, reject) => {
            S3.upload({
                Bucket: 'try753',
                Key: result[item].filename,
                Body: Buffer.from(result[item].content),
            }, (err, data) => {
                if (err) {
                    reject(err);
                }
                console.log(data);
                resolve(data);
            });
        }))))
        .then(() => {
            callback(null, response);
        });


};

在该函数中,我:

  1. 获取multipart / form-data
  2. 将数据提取到对象中3)
  3. 将文件保存到s3

但这是一个问题, 我得到了一个图像文件50Kb,在提取了数据之后,我得到了缓冲区50Kb, 但是,当我将文件保存到s3中时,文件大小为94Kb,并且已损坏。 在s3.upload期间会发生什么? 附言任何媒体文件都存在相同的问题。 P.S.S. txt文件没有问题。

1 个答案:

答案 0 :(得分:0)

要在API Gateway中支持二进制有效负载,必须通过将媒体类型添加到RestApi资源的binaryMediaTypes列表中或在contentHandling上设置Integration属性来配置API。 IntegrationResponse资源。

  

取决于contentHandling值以及Content-Type   响应标头或传入请求的Accept标头   匹配binaryMediaTypes列表中的条目,API网关可以编码   将原始二进制字节作为Base64编码的字符串,对   Base64编码的字符串返回其原始字节,或将正文传递   无需修改。

简单来说,取决于您的API网关配置,您的表单数据可能会或可能不会被编码,这在创建缓冲区时需要在代码中进行处理。使用Buffer.from(string[, encoding])中的第二个参数传递相应的编码。

这里是content type conversion table供您参考。

您可以在与contentHandling相同级别的 serverless.yml 文件中指定integration设置,例如:

integration: LAMBDA
contentHandling: CONVERT_TO_BINARY