尝试使用API​​ Gateway和Lambda从S3提供图片文件会导致文件损坏

时间:2019-10-06 18:02:42

标签: node.js amazon-web-services amazon-s3 aws-lambda aws-api-gateway

我创建了AWS API Gateway方法,该方法调用Lambda函数,该函数应将图像文件作为附件返回给用户。 API网关方法设置为使用Lambda代理集成(请求将代入Lambda)。我的Lambda函数非常简单:

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

exports.handler = async event => {
  try {
    const Bucket = event.xxx;
    const Key = event.yyy;
    const file = await s3.getObject({ Bucket, Key }).promise();

    return {
      body: file.Body.toString(),
      headers: {
        'Content-Disposition': `attachment; filename=test.jpg`,
        'Content-Length': file.ContentLength,
        'Content-Type': file.ContentType,
      },
      statusCode: 200,
    };
  } catch (e) {
    console.error(e);
  }
};

但是,以这种方式下载的文件的大小与原始文件不同,并且已损坏。

例如,我尝试上传81264字节的文件,但下载的版本为146650字节。
从Lambda检查响应标头,我发现Content-Length实际上是67432(即使将其设置为file.ContentLength的{​​{1}}),但是也有一个自定义标头{{ 1}}显示正确的大小(81264)。

我该怎么做才能正确响应并返回正确的文件?

1 个答案:

答案 0 :(得分:0)

这似乎与常规API网关设置更加相关,首先是在API设置(例如image/jpegapplication/pdf等)中定义“二进制媒体类型”,然后根据{{3} }该请求还应该发送Accept标头。

最后,我应该将Body转换为base64,并将isBase64Encoded: true添加到响应中,然后看起来像:

return {
  body: file.Body.toString('base64'),
  headers: {
    'Content-Disposition': `attachment; filename=test.jpg`,
    'Content-Length': file.ContentLength,
    'Content-Type': file.ContentType,
  },
  statusCode: 200,
  isBase64Encoded: true,
};