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

时间:2021-11-01 02:17:07

everybody here is my issue. I wrote an AWS Lambda with the next code:

这里的每个人都是我的问题。我用下一个代码写了一个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);
        });


};

In that function, I:

在那个职能中,我:

  1. get multipart/form-data
  2. 获取multipart / form-data
  3. extract data into an object 3)
  4. 将数据提取到对象中3)
  5. save files to s3
  6. 将文件保存到s3

but here is an issue, I got an image file 50Kb, and after data extraction, I get Buffer 50Kb, but when I save a file into s3, its size is 94Kb and it's spoiled. What happens with it during s3.upload? P.S. There are the same problems with any media file. P.S.S. There is no problem with txt files.

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

1 个解决方案

#1


0  

To support binary payloads in API Gateway, you must configure the API by adding the media types to the binaryMediaTypes list of the RestApi resource or set the contentHandling properties on the Integration and the IntegrationResponse resources.

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

Depending on the contentHandling value, and whether the Content-Type header of the response or the Accept header of the incoming request matches an entry in the binaryMediaTypes list, API Gateway can encode the raw binary bytes as a Base64-encoded string, decode a Base64-encoded string back to its raw bytes, or pass the body through without modification.

根据contentHandling值,以及响应的Content-Type标头或传入请求的Accept标头是否与binaryMediaTypes列表中的条目匹配,API Gateway可以将原始二进制字节编码为Base64编码的字符串,解码Base64 -encoded string返回其原始字节,或通过正文而不进行修改。

In simple words, depending you your API Gateway configuration, your form data may or may not be encoded, which needs to be handled in your code when you create a Buffer. Use the second parameter in Buffer.from(string[, encoding]) to pass corresponding encoding.

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

Here is the content type conversion table for your reference.

以下是内容类型转换表供您参考。

You can specify the contentHandling setting in serverless.yml file on the same level as integration, for example:

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

integration: LAMBDA
contentHandling: CONVERT_TO_BINARY

#1


0  

To support binary payloads in API Gateway, you must configure the API by adding the media types to the binaryMediaTypes list of the RestApi resource or set the contentHandling properties on the Integration and the IntegrationResponse resources.

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

Depending on the contentHandling value, and whether the Content-Type header of the response or the Accept header of the incoming request matches an entry in the binaryMediaTypes list, API Gateway can encode the raw binary bytes as a Base64-encoded string, decode a Base64-encoded string back to its raw bytes, or pass the body through without modification.

根据contentHandling值,以及响应的Content-Type标头或传入请求的Accept标头是否与binaryMediaTypes列表中的条目匹配,API Gateway可以将原始二进制字节编码为Base64编码的字符串,解码Base64 -encoded string返回其原始字节,或通过正文而不进行修改。

In simple words, depending you your API Gateway configuration, your form data may or may not be encoded, which needs to be handled in your code when you create a Buffer. Use the second parameter in Buffer.from(string[, encoding]) to pass corresponding encoding.

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

Here is the content type conversion table for your reference.

以下是内容类型转换表供您参考。

You can specify the contentHandling setting in serverless.yml file on the same level as integration, for example:

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

integration: LAMBDA
contentHandling: CONVERT_TO_BINARY