【问题标题】:How to download a Signed Google Storage URL on client machine如何在客户端计算机上下载签名的 Google 存储 URL
【发布时间】:2022-01-31 03:44:45
【问题描述】:

我有这段代码可以创建一个签名 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}"`
  );

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

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

更新:

从响应请求中可以看出:

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

【问题讨论】:

  • 我们试试res.header('Content-disposition', "attachment; filename=" + fileName);
  • @hoangdv 它只是再次查看文件它没有下载它

标签: node.js firebase express google-cloud-functions google-cloud-storage


【解决方案1】:

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

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

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

更新

为了使用 Google 存储管理 API 生成带有自定义标头(例如 Content-Disposition)的签名 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 参考以获取可能的标头值:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

请参阅用于 google 存储的 nodejs api 库的文档here 并链接到解释文件附件属性promptSaveAsresponseDisposition 的行here

【讨论】:

  • 感谢您的回答,但正如您在我的问题的下半部分看到的那样,我已经尝试过了。
  • 请查看更新后的问题
  • 来自 mdn doc:The first parameter in the HTTP context is either inline (default value, indicating it can be displayed inside the Web page, or as the Web page) or attachment (indicating it should be downloaded; most browsers presenting a 'Save as' dialog, prefilled with the value of the filename parameters if present). 所以,attachment 部分很重要,在您的情况下,inline 已发送。 developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…
  • 那我该如何阻止它发送“inline”呢?当我发送与您完全相同的标题时
  • 在调用 get signedUrl 时添加 responseDisposition 属性,并进行相应设置。检查此文件中的 jsdoc 行 2897-2902 github.com/googleapis/nodejs-storage/blob/main/src/file.ts
猜你喜欢
  • 2023-03-13
  • 2013-03-17
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 2020-12-03
  • 2010-11-28
  • 2012-12-13
  • 2019-08-10
相关资源
最近更新 更多