【发布时间】:2021-09-18 15:45:28
【问题描述】:
我正在构建一个 NodeJS Express API,它接受文件路径作为参数,从 S3 获取对象,然后在 API 响应中将文件发送回。
我正在使用 NodeJS Amazon AWS S3 开发工具包@aws-sdk/client-s3。
我已准备好在 API 响应中返回文件。
这里是控制器。这是从 S3 获取对象作为可读流的工作。
const consoleLogger = require('../logger/logger.js').console;
const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');
const s3client = new S3Client({ region: process.env.AWS_REGION || 'us-east-1' });
const awsCtrl = {};
awsCtrl.getObject = async (key) => {
// Get object from Amazon S3 bucket
let data;
try {
// Data is returned as a ReadableStream
data = await s3client.send(new GetObjectCommand({ Bucket: process.env.AWS_BUCKET, Key: key }));
console.log("Success", data);
} catch (e) {
consoleLogger.error("AWS S3 error: ", e);
const awsS3Error = {
name: e.name || null,
status: e.$metadata.httpStatusCode || 500
};
throw awsS3Error;
}
return data;
}
module.exports = awsCtrl;
这里是调用控制器的地方。
router.get('/:fileId', (req, res, next) => {
return filesCtrl.deliverFile(req, res);
});
filesCtrl.deliverFile = async (req, res) => {
/* Get object from AWS S3 */
let fileStream;
try {
fileStream = await awsCtrl.getObject(filePath);
} catch (e) {
consoleLogger.error(`Unable to get object from AWS S3`, e);
if (e.status && e.status === 404) {
result.error = `Not found`;
result.status = 404;
return res.status(result.status).json(result);
}
return res.status(e.status || 500).json(result);
}
// Set file header
res.attachment(filename);
// HOW TO RETURN THE FILE IN API RESPONSE TO DOWNLOAD?
// not working
//return fileStream.pipe(res);
}
问题:
如何在 Node JS Express API 响应中返回文件以供下载?
注意:我已经在其他几个问题中尝试了其他建议,但没有一个解决方案能够在 API 响应中返回文件。
我在这里尝试了这个问题的答案,但是文件是在服务器端下载的,文件需要在 API 响应中返回。 How to save file from S3 using aws-sdk v3
这里这个问题的答案是使用 SDK 的 v2 版本,这是 v3。不再有 .createReadStream() 方法。 NodeJS download file from AWS S3 Bucket
【问题讨论】:
-
我可能遗漏了一些东西......“API 响应”在您的上下文中是什么意思?这是快递吗?我对sdk的v3不熟悉,但是v2会返回一个缓冲区……你问如何返回二进制数据?
-
@404 是的,这是一个 NodeJS Express API。我想在 Express API 响应“res”中返回文件以在客户端下载文件。
-
您确定要将其作为文件发送吗? 或者 给客户端发一个下载链接可以吗,客户端可以用这个链接下载FE中的文件?
-
如果您使用的是 lambda,请不要这样做,请使用 S3 预签名网址!您将支付从 S3 到 lambda 的下载时间,以及从 lambda 到最终用户的下载时间。
-
ReadableStream是 Web Streams API 的一部分(在node:stream/web中实现)。我无法确认它是 s3 sdk 真正使用的,但如果是这种情况,则不应定义pipe()。相反,它应该是pipeTo()。但恐怕您将不得不将网络标准流转换为节点Readable流。
标签: node.js amazon-web-services amazon-s3