从AWS S3存储桶下载NodeJS文件

时间:2019-04-16 10:03:02

标签: javascript node.js amazon-web-services express amazon-s3

我试图在NodeJS / Express中创建一个终端节点,以从我的AWS S3存储桶下载内容。

效果很好,我可以在客户端下载文件,但也可以在“网络”标签中看到流预览,这很烦人...

  

问题

     

我想知道我在做什么是否正确和良好的做法。   还想知道在“网络”选项卡中看到输出流是否正常。

     

如何使用NodeJS / Express将文件从S3正确发送到客户端应用程序?

我很确定其他网站的请求也不允许您使用以下内容预览内容:“ 无法加载响应数据”。


这是我在NodeJS应用程序中从AWS S3获取流文件的操作:

download(fileId) {
  const fileObjectStream = app.s3
    .getObject({
      Key: fileId
    })
    .createReadStream();
  this.res.set("Content-Type", "application/octet-stream");
  this.res.set(
    "Content-Disposition",
    'attachment; filename="' + fileId + '"'
  );
  fileObjectStream.pipe(this.res);
}

在客户端,我可以看到:

enter image description here

1 个答案:

答案 0 :(得分:0)

我认为问题在于标题:

          //this line will set proper header for file and make it downloadable in client's browser

          res.attachment(key); 

          // this will execute download 
          s3.getObject(bucketParams)
          .createReadStream()
          .pipe(res);

所以代码应该是这样的(这是我在我的项目处理文件中以res.attachment或res.json进行的操作,以防出现错误,以便客户端可以向最终用户显示错误):

router.route("/downloadFile").get((req, res) => {
      const query = req.query; //param from client
      const key = query.key;//param from client
      const bucketName = query.bucket//param from client

      var bucketParams = {
        Bucket: bucketName,  
        Key: key
      };

      //I assume you are using AWS SDK
      s3 = new AWS.S3({ apiVersion: "2006-03-01" });

      s3.getObject(bucketParams, function(err, data) {
        if (err) {
          // cannot get file, err = AWS error response, 
          // return json to client
          return res.json({
            success: false,
            error: err
          });
        } else {
          res.attachment(key); //sets correct header (fixes your issue ) 
          //if all is fine, bucket and file exist, it will return file to client
          s3.getObject(bucketParams)
            .createReadStream()
            .pipe(res);
        }
      });
    });