NodeJS从AWS S3存储桶下载文件

7
我正在尝试在NodeJS/Express中创建一个端点,用于从我的AWS S3 Bucket下载内容。它的工作很好,我可以在客户端下载文件,但是我也可以在网络选项卡中看到流预览,这非常烦人...。 问题 我想知道我是否做得正确并且是否是良好的实践。同时还想知道在网络选项卡中看到输出流是否正常。如何使用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);
}

在客户端,我可以看到这个:

输入图像描述


3
我猜另一个选项是让Node.js创建一个签名URL,然后将其发送给客户端。客户端可以使用该签名URL来访问S3内容。 - dbramwell
1个回答

4
我认为问题出在头部信息上:
```

我认为问题出在头部信息上:

```
          //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);
        }
      });
    });

这会如何触发客户端的下载呢? - insivika
在客户端,适当的标题是触发文件的关键。在常规的HTTP响应中,Content-Disposition响应头是一个指示内容是否预期在浏览器中内联显示的头部,即作为Web页面或Web页面的一部分,或作为附件,即下载并本地保存。例如,Content-Disposition: attachment; filename="whateverIfFileName.jpg"将向浏览器发送下载文件的指示......在我的代码中,res.attachment(key)是设置正确的文件头的关键,以便浏览器可以下载文件。我希望这可以帮助到您。 - StefaDesign
当我尝试下载时,下载速度非常慢。可能是什么原因呢? - prince david
可能会有多种事件导致速度变慢。我能想到的一些原因是:连接缓慢或不稳定(通常是你这边的互联网连接)。这可能是主要原因,也可能是文件大小(根据你下载的是视频、图像还是文本文件而定)。另一个我能想到的问题是,在你到达 S3 之前,你的机器(计算机)在网络中的设置方式(隧道、VPN、代理等),也许从你的机器到 S3 的流量有间接路线,这可能会导致一些速度问题。 - StefaDesign

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接