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

React中从Supabase获取图片显示失败,报400及资源未找到错误

Supabase图片加载失败(400/资源未找到)问题解决

核心问题1:异步函数直接作为img src值

你的getSignedUrl是异步函数,直接在img的src属性中调用会返回[object Promise],而非有效的图片URL,这是导致请求错误的直接原因。

修复方案:预取签名URL

提前为所有项目获取并存储签名URL,避免在渲染时直接调用异步函数:

const Dashboard = () => {
  const [projects, setProjects] = useState<Project[]>([])
  // 用对象映射项目ID与对应签名URL
  const [signedUrls, setSignedUrls] = useState<Record<string, string>>({})

  useEffect(() => {
    getProjects()
  }, [])

  const getProjects = async () => {
    try {
      const {data: projects, error} = await supabase.from('Projects').select('*')
      if (error) throw error
      setProjects(projects as Project[])
      // 批量获取所有项目的签名URL
      await fetchAllSignedUrls(projects as Project[])
    } catch (error) {
      console.error('获取项目列表失败:', error)
    }
  }

  const fetchAllSignedUrls = async (projects: Project[]) => {
    const urlMap: Record<string, string> = {}
    for (const project of projects) {
      if (!project.logo) continue
      try {
        const {data} = await supabase.storage.from('project-logo').createSignedUrl(project.logo, 60)
        urlMap[project.id] = data.signedUrl
      } catch (error) {
        console.error(`获取${project.name}的logo URL失败:`, error)
      }
    }
    setSignedUrls(urlMap)
  }

  return (
    <div className='row'>
      {projects.map((project) => (
        <div className='col-lg-4 mb-5' key={project.id}>
          <div className='card card-custom card-stretch-50 shadow'>
            <div className='card-header d-flex align-items-center'>
              <a href={`/project/${project.id}/detail`}>
                <h3 className='card-title'>{project.name}</h3>
              </a>
              {/* 使用预取的URL,添加加载状态兜底 */}
              {signedUrls[project.id] ? (
                <img src={signedUrls[project.id]} alt={project.name} />
              ) : (
                <span>加载中...</span>
              )}
            </div>
            <div className='card-body'>{project.description}</div>
          </div>
        </div>
      ))}
    </div>
  )
}

问题2:文件路径不匹配

检查Projects表logo列存储的路径是否和Supabase存储桶内的实际路径完全一致:

  • 若图片存放在桶内的子文件夹(如logos/xxx.png),确保数据库中存储的是完整路径,而非仅文件名
  • 注意路径大小写,Supabase存储路径区分大小写

问题3:存储桶权限不足

确认project-logo存储桶的读取权限已正确配置:

  1. 进入Supabase控制台的「存储」页面,选择project-logo桶
  2. 在「Policies」标签下,创建或确认存在允许读取的策略,示例SQL:
CREATE POLICY "允许读取项目logo" ON storage.objects
FOR SELECT USING (bucket_id = 'project-logo');

额外优化:完善错误处理

原代码中getProjects的catch块为空,建议添加错误日志输出,方便排查潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:07:27