如何在客户端计算机上下载签名 Google 存储 URL

How to download a Signed Google Storage URL on client machine

我有这段代码可以创建签名 URL 来下载我存储桶中的特定文件:

exports.download = functions.https.onRequest((req, res) => {
  const userID = req.query.userID;
  const downloadID = req.query.downloadID;
  const fileName = req.query.fileName;

  admin
    .storage()
    .bucket()
    .file(`userUploads/${userID}/${downloadID}/${fileName}`)
    .getSignedUrl({
      version: "v4",
      action: "read",
      expires: Date.now() + 15 * 60 * 1000, // 15 minutes
    })
    .then((signedURLArray) => {
      const url = signedURLArray[0];
      // return res.download(url);
      return res.redirect(url);
    })
    .catch((err) => {
      return res.send(err);
    });
});

我试过:

res.setHeader(
    `"content-disposition", "attachment; filename=${fileName}"`
  );

with res.redirect 但它只是给了我一个 HTTP_TOKEN_ERROR 。如果我使用 res.redirect() 而不设置任何额外的 headers,它只会在浏览器上查看文件,而不是下载它 - 我只希望用户能够下载文件。

显然,res.download 不起作用,因为有问题的文件不在服务器上,它在我的存储桶文件所在的其他服务器上提供(很可能是某些 storage.googleapis.com 域)

更新:

从响应请求可以看出:

它正在将正确的数据发送回浏览器

当您重定向到 google 的服务器时,它会负责响应的 header,特别是 Content-disposition。存储在 google 存储中的文件的元数据可以在文件上传时或之后设置。 您的 header 应如下所示:

Content-Disposition: attachment; filename="file.ext..."

请查看这些文档以查看有关如何通过 gsutil 手动设置文件元数据的可能选项:

更新

为了使用自定义 header(例如 Content-Disposition)和 Google 存储管理员 API 生成签名 URL,应该通过配置参数 responseDisposition 具有所需的值

用法示例:

...
admin
    .storage()
    .bucket()
    .file(`userUploads/${userID}/${downloadID}/${fileName}`)
    .getSignedUrl({
      responseDisposition: "attachment",
      version: "v4",
      action: "read",
      expires: Date.now() + 15 * 60 * 1000, // 15 minutes
    })
...

请参阅 MDN 参考以了解可能的 header 值:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

请参阅 nodejs api 库的文档,用于 google 存储 here and link to the lines where file attachment properties, promptSaveAs and responseDisposition are explained here