无法使用 Node.js 的 Admin SDK 在 Firebase 存储中将 Content-Disposition 覆盖为 'inline'

Can't Override Content-Disposition to 'inline' in Firebase Storage with Admin SDK for Node.js

我想将 Firebase 存储中的默认 content-disposition: attachment HTTP header 覆盖为 content-disposition: inline,以便从我的存储中提供由浏览器打开的 public 图片(如 <a href="..."> 链接)供查看(未下载)。

重要的默认 header 如下:

content-disposition: attachment
content-type: image/jpeg

默认下载图像,我认为这是 content-disposition: attachment 强制的,这就是为什么我在 Firebase Admin SDK 中上传时尝试覆盖它的原因:

bucket.upload(photoUrl, {
  destination,
  public: true,
  metadata: {
    contentDisposition: 'inline',
  },
}).then((data) =>
  console.log(data[1].mediaLink),
);

我清除了存储中的所有图像并使用此代码上传新图像,但我仍然得到 content-disposition: attachment。也许是设计使然,也许我的代码是错误的。

图像的 URL 如下所示:https://www.googleapis.com/download/storage/v1/b/MY_PROJECT/o/IMAGE_PATH?generation=SOME_NUMBER&alt=media

如果可能的话,将 content-disposition 覆盖为 inline 的正确方法是什么?

相关问题:From firebase storage download file to iframe

更新

在 Chrome devtools 控制台中我收到警告:"Resource interpreted as Document but transferred with MIME type image/jpeg"。我尝试将 .jpg 扩展附加到上传的图像目标,但我仍然收到此警告。

元数据字段称为 Content-Disposition。您是否尝试过类似以下的方法?

const meta = {};
meta['Content-Disposition'] = 'inline';
bucket.upload(photoUrl, {
  destination,
  public: true,
  metadata: meta,
});

官方回答

我已将来自@stephenplusplus 的问题发布到 nodejs-storage on GitHub and got this response

I believe you'll need to use a signed URL for this behavior. The mediaLink address appears to be meant for downloading, and also requires authorization to access (unless you made your bucket/file public).

A signed URL will create a unique URL for users to access, unrelated to the privacy of the Object in GCS. It will also inherit the metadata you set. To get a signed URL that opens in the browser...

根据他的回答修改代码:

bucket.upload(photoUrl, {
  destination,
}).then((data) => {

  const file = data[0];
  return file.getSignedUrl({
    action: 'read',
    expires: '12-31-2118',
  });
}).then((data) =>
  console.log(data[0]),
);

signed URLs in Cloud Storage documentation and File.getSignedUrl for NodeJS

解决方法

const blob = await fetch(mediaLink).then((res) => res.blob());
const blobUrl = URL.createObjectURL(blob);
// To keep adblockers away from your window:
const win = window.open();
win.document.head.innerHTML = `...<img src="${blobUrl}">...`;