【问题标题】:NodeJS Amazon AWS S3 getObject how to send file in API response to downloadNodeJS Amazon AWS S3 getObject如何在API响应中发送文件以下载
【发布时间】: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


【解决方案1】:

服务器端

const aws = require('aws-sdk');

router.get('/getfilefroms3', async (req, res, next) => {

  aws.config.update({
    secretAccessKey: config.secret_access_key,
    accessKeyId: config.access_key_id,
    signatureVersion: config.signature_version,
    region: config.region
  })

  const s3 = new aws.S3({ });

  var params = { Bucket: config.sample_bucket_name, Key: req.query.filename };

  s3.getObject(params, function (err, data) {
    if (err) {
      res.status(200);
      res.end('Error Fetching File');
    }
    else {
      res.attachment(params.Key); // Set Filename
      res.type(data.ContentType); // Set FileType
      res.send(data.Body);        // Send File Buffer
    }
  });

})

客户端

如果您使用的是 Web 应用程序,您可以使用任何 HTTP REST API 客户端,例如 Axios 或 Fetch,下载管理器将捕获文件。

curl --location --request GET 'http://localhost:5001/getfilefroms3?filename=sample.pdf'

如果您使用的是 NodeJS 应用程序

var http = require('http');
var fs = require('fs');

var download = function (url, destination, callback) {
    var file = fs.createWriteStream(destination);
    http.get(url, function (response) {
        response.pipe(file);
        file.on('finish', function () {
            file.close(callback);
        });
    });
}

var fileToDownload = "sample.pdf"

download("http://localhost:5001/getfilefroms3?filename=" + fileToDownload, "./" + fileToDownload, () => { console.log("File Downloaded") })

【讨论】:

    猜你喜欢
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 2019-02-08
    • 1970-01-01
    • 2021-06-26
    • 2019-09-06
    • 2012-05-11
    相关资源
    最近更新 更多