将 Lambda 处理程序响应正文作为流发送

问题描述 投票:0回答:2

似乎有一百万个问题与我的相关,但建议的解决方案都不起作用,或者只是不同,对我没有帮助。

我有一个带有下载按钮的 UI,用户可以在其中从 S3 获取 zip 文件,但在本应完成此操作的 lambda 函数中,我遇到了多个错误。

我有一个使用 Express 的工作解决方案,但我现在需要使用无服务器框架。

这是我在 Express 框架中的工作解决方案:

const zip = new AdmZip(data.Body);
const entries = zip.getEntries();
let newZip = new AdmZip();
for(let entry of entries){
    newZip.addFile(entry.entryName, entry.getCompressedData());
}
newZip.writeZip(__dirname + `/${file}.zip`);
let fileToSend = fs.createReadStream(`${file}.zip`);
fileToSend.pipe(res);

我使用 AdmZip 从下载的缓冲区中创建一个新的 zip 文件,然后将其作为流发送到响应对象,这绝对是 hacky 但正在工作,所以我暂时对此感到满意。

我尝试过使用无服务器框架和 Lambda 函数的类似解决方案,如下所示:

const fs = require('fs/promises');
module.exports.handler = async (event) => {
       const response = {
          isBase64Encoded: false,
          statusCode: 200,
       };

       try {
        const params = {
            Bucket: BUCKET_NAME,
            Key: decodeURIComponent(event.pathParameters.fileKey),
        };
        const data = await s3.getObject(params).promise();
        const zip = new AdmZip(data.Body);
        const entries = zip.getEntries();
        let newZip = new AdmZip();
        for(let entry of entries){
            newZip.addFile(entry.entryName, entry.getCompressedData());
        }
        newZip.writeZip(__dirname + `/${fileName}.zip`);
        var fileToSend = fs.createReadStream(`${fileName}.zip`);
        fileToSend.pipe(response.body);
       } catch (error) {
         console.error(error);
         response.body = JSON.stringify({ message: 'Failed To Get File', errorMessage: error });
         response.statusCode = 500;
    }
return response;
};

但是在使用此代码时,它在本地目录中成功创建了文件,但引发了错误 类型错误:fs.createReadStream 不是函数

我已经研究过,这似乎是承诺的问题,但对于流我很无知。

此时,我希望有人帮助编辑我现有的代码,或者为我指明完全不同的方向。

提前致谢

node.js amazon-s3 aws-lambda response serverless-framework
2个回答
0
投票

Lambda 现在支持通过 Lambda 函数 URL 进行流式传输。这不适用于 API GateWay。

https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html

样品:

const pipeline = require("util").promisify(require("stream").pipeline);
const { Readable } = require('stream');

exports.echo = awslambda.streamifyResponse(async (event, responseStream, _context) => {
  // As an example, convert event to a readable stream.
  const requestStream = Readable.from(Buffer.from(JSON.stringify(event)));

  await pipeline(requestStream, responseStream);
});

0
投票

我构建了一个简单的产品,可以为您处理压缩功能。看看:streamzipper.com

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.