我遇到了一个问题,AWS lambda损坏我的图像缓冲区,当我尝试将它发送到一个不一致的webhook。它在本地与SLS脱机工作,我可以看到不一致的通道中的图像没有问题,但当我将它部署到AWS时,我得到
而不是图片本身。看看周围类似的人与这个问题,我已经尝试添加到我的serverless. yml
plugins:
- serverless-apigw-binary
自定义路径中包含apigwBinary
。
apigwBinary:
types: #list of mime-types
- 'image/png'
我还看到另一篇关于在serverless. yml中的provider下添加AwsApiGateway
的帖子,如下所示
provider:
AwsApiGateway:
binaryMediaTypes:
- 'image/png'
当我console.log('Sending Buffer', buffer);
缓冲区以确保它确实存在于cloudwatch中时,我看到
Sending Buffer <Buffer fd 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 04 fd 00 00 02.... 162236 more bytes>
所以缓冲区肯定会进入lambda,但当它不一致时会损坏。但它在本地工作时也没有任何问题。所以Lambda不知何故损坏了它。我甚至尝试添加3秒延迟,看看这是否可以修复它,就像它是一个竞争条件或其他东西一样,即使我可以在控制台日志中看到缓冲区,但没有。
webhook.send({
files: [{
attachment: buffer,
name: newFileName
}]
})
.then((res) => {
console.log('FINISHED', res);
});
}
catch (e) {
console.log('ERROR', e);
}
更新:
我还尝试将图像上传到S3,看看图像是否会在那里损坏,并再次在本地上传时文件是好的,但从Lambda上传到S3时没有。同样的问题。图像损坏。我还注意到,从SLS离线上传时的文件大小比lambda版本大了50字节,因此从cloudfront进行了一些奇怪的压缩,可能是导致图像损坏。
将图像从Angular发送到Lambda再发送到Discord的端到端代码
分量
const table = document.getElementById('table');
const canvas = await html2canvas(table);
console.log('canvas', canvas);
const image: any = await getCanvasBlob(canvas);
this.angularService
.postImageToDiscord(image)
.pipe(takeUntil(this.destroy))
.subscribe((res) => {
this.isLoading = false;
});
Angular 服务
postImageToDiscord(imageData: File) {
let formData = new FormData();
formData.append('file', imageData, 'file.png');
const body = { file: imageData };
const api = environment.baseUrl + '/post-image';
const req = new HttpRequest('POST', api, formData);
return this.http.request(req);
}
无服务器函数定义
functions:
sendImageToDiscord:
handler: src/handler.sendImageToDiscord
events:
- http:
path: /post-image
method: post
cors: true
handler.ts
import { parser } from './parser';
export const sendImageToDiscord = async (
event: any,
context: Context
): Promise<ProxyResult> => {
const parsedEvent: any = await parser(event);
try {
await postImageTableToDiscord(
parsedEvent.body.file,
event.queryStringParameters.assetType
);
} catch (e) {
console.log('ERROR HERE', e);
}
const response = {
statusCode: 200,
body: JSON.stringify('file sent successfully')
};
return response;
};
从处理程序导入的分析程序文件
const Busboy = require('busboy');
const getContentType = (event: any) => {
const contentType = event.headers['content-type'];
if (!contentType) {
return event.headers['Content-Type'];
}
return contentType;
};
export const parser = (event: any) =>
new Promise((resolve, reject) => {
const busboy = new Busboy({
headers: {
'content-type': getContentType(event)
}
});
let result: any = {
file: '',
filename: '',
contentType: ''
};
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
file.on('data', (data) => {
result.file = data;
});
file.on('end', () => {
result.filename = filename;
result.contentType = mimetype;
});
});
busboy.on('field', (fieldname, value) => {
result[fieldname] = value;
});
busboy.on('error', (error: any) => reject(error));
busboy.on('finish', () => {
event.body = result;
resolve(event);
});
busboy.write(event.body, event.isBase64Encoded ? 'base64' : 'binary');
busboy.end();
});
我很感激你的帮助。
1条答案
按热度按时间o4tp2gmn1#
您是否尝试过将HTTP响应的Content-Type标头设置为“image/png”?