You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Fetch API获取Firebase Storage图片返回空Blob问题求助

问题分析与解决方案

首先,你遇到的空Blob问题,核心原因是**mode: 'no-cors'的限制**。当使用no-cors模式时,浏览器会返回一个「不透明响应(opaque response)」,这种响应的内容是无法被JavaScript读取的——这就是为什么你得到Blob {size: 0, type: ""}的原因。

另外,虽然你的图片URL带了下载token,理论上可以绕过Firebase的认证规则,但no-cors模式直接阻断了响应内容的读取,这才是关键问题。

下面给你几个可行的解决方案:

方案1:移除mode: 'no-cors',并确保请求能通过认证

因为你的Firebase Storage规则要求request.auth != null,如果你的前端已经有用户登录(通过Firebase Auth),可以直接移除no-cors模式,同时让Fetch请求带上认证信息。修改后的代码如下:

getImage = async () => { 
  const url = "https://firebasestorage.googleapis.com/v0/b/alpha-c790f.appspot.com/o/images%2Frivers.jpg?alt=media&token=6a96d672-23c1-425f-bdca-47f6d73608f0";
  try {
    // 如果已经通过Firebase Auth登录,获取当前用户的ID Token
    const user = firebase.auth().currentUser;
    const idToken = await user.getIdToken();

    const response = await fetch(url, {
      headers: {
        Authorization: `Bearer ${idToken}`
      }
    });

    if (!response.ok) {
      throw new Error(`请求失败:${response.status}`);
    }

    const res = await response.blob();
    console.log(res); 
    const objectURL = URL.createObjectURL(res); 
    const myImage = new Image(); 
    myImage.src = objectURL;
    // 这里可以监听myImage的load事件,隐藏加载动画
    myImage.onload = () => {
      console.log("图片加载完成");
      // 执行你的加载动画隐藏逻辑
    };
  } catch(err) { 
    console.log(err); 
  }
}

方案2:利用图片的onload事件实现加载动画(无需Fetch)

其实你不需要用Fetch来实现「加载完成前显示动画」的需求,直接用<img>标签的onload事件就可以做到,这样更简单,还能避免CORS相关的问题:

<!-- 页面中的HTML -->
<div class="loading-spinner" id="loadingSpinner">加载中...</div>
<img id="targetImage" style="display: none;" />
// JavaScript代码
const loadingSpinner = document.getElementById('loadingSpinner');
const targetImage = document.getElementById('targetImage');

targetImage.onload = () => {
  // 图片加载完成,隐藏加载动画,显示图片
  loadingSpinner.style.display = 'none';
  targetImage.style.display = 'block';
};

targetImage.onerror = () => {
  loadingSpinner.textContent = '图片加载失败';
};

// 设置图片地址
targetImage.src = "https://firebasestorage.googleapis.com/v0/b/alpha-c790f.appspot.com/o/images%2Frivers.jpg?alt=media&token=6a96d672-23c1-425f-bdca-47f6d73608f0";

这种方式不需要处理Fetch的CORS问题,直接利用浏览器原生的图片加载事件,就能完美实现加载动画的需求。

方案3:调整Firebase Storage规则(不推荐,除非公开访问)

如果你的图片是可以公开访问的,可以修改Storage规则为:

rules_version = '2'; 
service firebase.storage { 
  match /b/{bucket}/o { 
    match /{allPaths=**} { 
      allow read: if true; 
      allow write: if request.auth != null; 
    } 
  } 
}

修改后,你可以移除mode: 'no-cors',直接用Fetch获取Blob,同时不需要携带认证信息。但注意,这样所有用户都能访问你的图片,安全性要根据你的业务需求判断。


内容的提问来源于stack exchange,提问作者Paramveer Kahlon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 11:14:05