amazon-web-services - AWS SDK Amazon S3 上传方法破坏图像文件
问题描述
这里的每个人都是我的问题。我用下面的代码写了一个 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);
});
};
在那个函数中,我:
- 获取多部分/表单数据
- 将数据提取到对象中 3)
- 将文件保存到 s3
但这里有一个问题,我得到了一个 50Kb 的图像文件,数据提取后,我得到了 50Kb 的缓冲区,但是当我将文件保存到 s3 时,它的大小是 94Kb 并且被破坏了。在 s3.upload 期间会发生什么?PS 任何媒体文件都有同样的问题。PSS txt 文件没有问题。
解决方案
要在 API Gateway 中支持二进制负载,您必须通过将媒体类型添加到 RestApi 资源的binaryMediaTypes列表或在Integration和IntegrationResponse资源上设置contentHandling属性来配置 API 。
根据 contentHandling 值,以及响应的 Content-Type 标头或传入请求的 Accept 标头是否与 binaryMediaTypes 列表中的条目匹配,API Gateway 可以将原始二进制字节编码为 Base64 编码的字符串,解码 Base64 -编码的字符串返回其原始字节,或不加修改地传递正文。
简而言之,根据您的 API Gateway 配置,您的表单数据可能会或可能不会被编码,这需要在您创建 Buffer 时在代码中进行处理。使用第二个参数Buffer.from(string[, encoding])
传入相应的编码。
这是内容类型转换表供您参考。
您可以contentHandling
在serverless.yml文件中指定与 相同级别的设置integration
,例如:
integration: LAMBDA
contentHandling: CONVERT_TO_BINARY
推荐阅读
- python - 从 MySQL DB 中的文本区域插入文本(Python/Flask)
- javascript - 获取 VSCode 以识别变量正在不同的 javascript 文件中使用
- mysql - 来自多个表的总和的数据透视表
- javascript - 我有 3 个 div,如何通过单击(一个接一个)选择 2 个 div 并在 Javascript 中不显示(或其他)第三个
- java - 二叉树 - 如何删除元素;爪哇
- c++ - 为什么我会出现运行时错误:加载类型为“_Bit_type”(stl_bvector.h)的空指针?
- c# - 给定 json 作为响应,但不确定如何解析它
- android - Tomtom android SDK中的地理搜索类型在哪里
- reactjs - React JS 错误:“组件”未定义
- python - 为什么 R 可以开箱即用,但 Python (matplotlib) 需要 tkinter?