#node.js #amazon-s3 #aws-lambda #response #serverless-framework
Вопрос:
Похоже, что есть миллион вопросов, связанных с моими, но ни одно из предложенных решений не работает или просто отличается настолько, что они мне не помогают.
У меня есть пользовательский интерфейс с кнопкой загрузки, где пользователи могут получать zip-файлы из S3, но в моей функции 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-файла из загруженного буфера, а затем отправляю его объекту ответа в виде потока, который определенно является хакерским, но работает, поэтому я был доволен им на данный момент.
Я попробовал аналогичное решение с использованием бессерверной платформы и лямбда-функции, которая выглядит следующим образом:
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;
};
Но при использовании этого кода он успешно создает файл в локальном каталоге, но выдает ошибку
TypeError: fs.createReadStream не является функцией
Что я изучил, и, похоже, это проблема с обещаниями, но я совершенно невежествен, когда дело доходит до потоков.
На данный момент я бы хотел, чтобы кто-нибудь помог мне либо отредактировать мой существующий код, либо указать мне совершенно другое направление.
Заранее спасибо
Комментарии:
1.
fs/promises
не имеетcreateReadStream
метода, вместо этого вам нужно получить его от:const { createReadStream } = require('fs');
, дайте мне знать, если это решит вашу проблему2. Я добавил
const { createReadStream } = require('fs');
и реализовал сlet fileToSend = createReadStream(``${event.pathParameters.fileKey}.zip``);
помощью, но я получил ошибку: Ошибка типа : Не удается прочитать свойство «включено» неопределенного3. как насчет использования этого кода?
fs.createReadStream(__dirname ``/${fileName}.zip``);
4. @tam.teixeira, у которого были аналогичные результаты, но я думаю, что проблема связана с тем, что «Объект ответа должен быть совместим с JSON.stringify» ( ссылка на документацию AWS). Поэтому я не уверен, куда идти дальше, если это ограничение обработчика Лямбда