【问题标题】:Piping a file straight to the client using Node.js and Amazon S3使用 Node.js 和 Amazon S3 将文件直接传送到客户端
【发布时间】:2019-04-26 12:07:10
【问题描述】:

所以我想将文件直接传送到客户端;我目前的做法是在磁盘上创建一个文件,然后将该文件直接发送到客户端。

router.get("/download/:name", async (req, res) => {

  const s3 = new aws.S3();
  const dir = "uploads/" + req.params.name + ".apkg"
  let file = fs.createWriteStream(dir);

  await s3.getObject({
    Bucket: <bucket-name>,
    Key: req.params.name + ".apkg"
  }).createReadStream().pipe(file);

  await res.download(dir);
});

我刚刚查到res.download() 仅在本地提供服务。有没有办法可以直接从 AWS S3 下载到客户端?即管道文件直接给用户。提前致谢

【问题讨论】:

    标签: node.js express download aws-sdk-js aws-sdk-nodejs


    【解决方案1】:

    如this SO thread中所述:
    您可以简单地将读取流传输到响应中,而不是将其传输到文件中,只需确保提供正确的Content-Type 并将其设置为附件,以便浏览器知道如何正确处理响应。

    res.attachment(req.params.name);
    await s3.getObject({
        Bucket: <bucket-name>,
        Key: req.params.name + ".apkg"
    }).createReadStream().pipe(res);
    

    更多的模式是直接为 S3 对象创建一个签名的 url,然后让客户端直接从 S3 下载,而不是从您的节点网络服务器流式传输。这将减少您的网络服务器的工作量。

    您需要使用 AWS S3 SDK for JS 中的 getSignedUrl 方法。
    然后,一旦您有了 URL,只需将其返回给您的客户端以自行下载文件。

    您应该考虑到,一旦您为客户提供了一个具有下载权限的签名 URL,例如 5 分钟,他们将只能在接下来的 5 分钟内下载该文件。您还应该考虑到,他们将能够在这 5 分钟内将该 URL 传递给其他任何人进行下载,因此这取决于您需要该 URL 的安全性。

    【讨论】:

      【解决方案2】:

      S3 可用于内容,所以我将执行以下操作。

      1. 在您的节点响应中添加 CORS 标头。这将使浏览器能够从另一个来源(即 S3)下载。
      2. 在您的存储桶上启用 S3 Web 服务器。
      3. 从 S3 下载重定向的脚本 - 这可以在 JS 中实现。

      如果您需要保护 S3 内容,请按照其他帖子中的建议使用签名 URL。

      【讨论】:

        猜你喜欢
        • 2014-12-06
        • 2017-07-23
        • 1970-01-01
        • 1970-01-01
        • 2013-07-09
        • 1970-01-01
        • 2014-02-22
        • 1970-01-01
        • 2019-10-11
        相关资源
        最近更新 更多