尝试使用API Gateway和Lambda从S3提供图像文件会导致文件损坏
我创建了调用Lambda函数的AWS API Gateway方法,该方法应将图像文件作为附件返回给用户。 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
,即81264
),但是还有一个自定义头x-amzn-Remapped-Content-Length
,它显示正确的大小(81264
])。
我应该怎么做才能正确响应并返回正确的文件?
回答如下:[这看起来与一般的API网关设置有关,从在API设置(例如image/jpeg
,application/pdf
等)中定义“二进制媒体类型”开始,然后根据"API Gateway Response Content Type Conversions"判断,请求还应该发送[ C0]标头。
最后,我应该将Accept
转换为Body
,并在响应中添加base64
,然后看起来像:
isBase64Encoded: true