NodeJS AWS Lambda损坏图像缓冲区-无服务器框架

3htmauhk  于 2023-03-01  发布在  Node.js
关注(0)|答案(1)|浏览(122)
    • bounty已结束**。回答此问题可获得+100声望奖励。奖励宽限期将在14小时后结束。user6680希望引起更多人关注此问题:我在从AWS Lambda发送缓冲区到Discord通道时遇到了问题。正如您在post中的屏幕截图中所看到的,它将缓冲区发送到通道,但它不会渲染图像。我可以控制台记录缓冲区并查看它,它可以在本地使用SLS离线,但当将其部署到AWS时,Lambda会破坏图像。我做错了什么?我感谢任何帮助!

我遇到了一个问题,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();
    });

我很感激你的帮助。

o4tp2gmn

o4tp2gmn1#

您是否尝试过将HTTP响应的Content-Type标头设置为“image/png”?

.then((res) => {
  console.log('FINISHED', res);
  return {
    statusCode: 200,
    headers: {
      'Content-Type': 'image/png'
    },
    body: ''
  };
})

相关问题