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

使用Supabase+NextJS-13开发待办应用时遇TypeError: fetch failed

NextJS 13 + Supabase 出现 TypeError: fetch failed 无法获取列表数据

问题概述

使用Supabase和NextJS 13开发待办列表应用时,从Supabase获取Lists表数据时服务器抛出TypeError: fetch failed错误。

数据库结构

Supabase中Lists表包含三列:

  • id:Supabase自动生成
  • created_at:Supabase自动生成
  • list_name:客户端传入字段

相关代码

Database.ts

import { createClient } from "@supabase/supabase-js";

const supabase_url = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabase_api_key = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;

const options = {
  auth: {
    persistSession: true,
    storageKey: "supabase",
  },
};

const supabase = createClient(supabase_url, supabase_api_key, options);
export default supabase;

export async function getLists() {
  let { data: lists, error } = await supabase.from("Lists").select("*");

  if (error) {
    console.log(error);
    return [];
  }

  return lists;
}

export async function addList({ list_name }: { list_name: string }) {
  const { data, error } = await supabase
    .from("Lists")
    .insert([{ list_name: list_name }])
    .select();

  if (error) {
    console.log(error);
    return;
  }

  return data;
}

export async function deleteList(list_id: number) {
  const { error } = await supabase.from("Lists").delete().eq("id", list_id);

  if (error) {
    console.log(error);
  } else {
    console.log("Deleted", list_id);
  }
}

/api/lists/route.ts

import { getLists } from "@/app/utils/Database";
import { NextResponse } from "next/server";

export async function GET() {
  let lists = await getLists();
  if (!lists) {
    lists = [];
  }
  return NextResponse.json(lists);
}

已尝试的无效方案

  • 设置persistSession=false,仍出现其他fetch错误
  • 配置storageKey参数,问题依旧
  • 将localhost改为127.0.0.1
  • Node.js版本从20.2降级至18.15
  • 删除node_modules并重新安装依赖

排查与解决方案

1. 验证环境变量配置

确认.env.local文件中的NEXT_PUBLIC_SUPABASE_URL和NEXT_PUBLIC_SUPABASE_ANON_KEY是否正确,无多余空格或引号。可在getLists函数中添加日志验证:

console.log('Supabase URL:', supabase_url);
console.log('Supabase Anon Key:', supabase_api_key);

2. 检查Supabase行级安全(RLS)规则

登录Supabase控制台,进入Lists表的权限页面:

  • 若开启RLS,需添加允许匿名用户读取数据的规则:
    CREATE POLICY "Allow anonymous read access to lists" ON public."Lists"
    FOR SELECT USING (true);
    
  • 可暂时关闭RLS测试,确认是否为权限导致的问题。

3. 优化服务器端Supabase客户端配置

NextJS API路由属于服务器端环境,无需浏览器存储相关配置,修改客户端初始化代码:

const options = {
  auth: {
    persistSession: false, // 服务器端禁用会话持久化
  },
};

如果是在Server Components中使用,建议使用官方的auth-helpers:

import { createServerComponentClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';

export async function getLists() {
  const supabase = createServerComponentClient({ cookies });
  let { data: lists, error } = await supabase.from("Lists").select("*");

  if (error) {
    console.error(error);
    return [];
  }

  return lists;
}

4. 直接测试Supabase API连通性

在浏览器中访问以下地址(替换为你的实际环境变量值):

{你的NEXT_PUBLIC_SUPABASE_URL}/rest/v1/Lists?select=*

请求头中添加apikey: {你的NEXT_PUBLIC_SUPABASE_ANON_KEY},查看是否能正常返回数据,验证网络连通性。

5. 捕获详细错误信息

修改getLists和API路由代码,打印完整错误细节:

// Database.ts
export async function getLists() {
  try {
    let { data: lists, error } = await supabase.from("Lists").select("*");
    if (error) throw error;
    return lists;
  } catch (err) {
    console.error('Get lists error:', err);
    return [];
  }
}

// route.ts
export async function GET() {
  try {
    const lists = await getLists();
    return NextResponse.json(lists || []);
  } catch (err) {
    console.error('API route error:', err);
    return NextResponse.json({ error: 'Failed to fetch lists' }, { status: 500 });
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:57:29