如何在客户端计算机上下载签名 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 手动设置文件元数据的可能选项:
- https://cloud.google.com/storage/docs/gsutil/addlhelp/WorkingWithObjectMetadata
- https://cloud.google.com/storage/docs/metadata#content-disposition
更新
为了使用自定义 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。
我有这段代码可以创建签名 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 手动设置文件元数据的可能选项:
- https://cloud.google.com/storage/docs/gsutil/addlhelp/WorkingWithObjectMetadata
- https://cloud.google.com/storage/docs/metadata#content-disposition
更新
为了使用自定义 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。