首页 > 解决方案 > 使用 Node.js 和 Amazon S3 将文件直接传送到客户端

问题描述

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

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.jsexpressdownloadaws-sdk-jsaws-sdk-nodejs

解决方案


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

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

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

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

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


推荐阅读