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

Next.js 13(App目录)调用内置API报错:无效URL问题求助

解决Next.js 13 App Router中调用Pages API路由的路径错误问题

问题原因

你在App Router的服务器组件(src/app/page.tsx默认是服务器组件)中使用相对路径/api/products调用fetch时,服务器端执行环境没有当前域名的上下文,无法自动补全base URL,导致解析路径失败。而浏览器客户端环境会自动用当前页面域名补全相对路径,所以用完整URL能正常工作。

三种可行解决方案

方案1:将fetch逻辑移到客户端组件

在客户端组件中使用相对路径调用API,浏览器会自动处理路径补全:

// src/app/ProductsClient.tsx
'use client';

import { useEffect, useState } from 'react';

interface Product {
  id: number;
  name: string;
  // 补充你的产品字段
}

const ProductsClient = () => {
  const [products, setProducts] = useState<Product[]>([]);

  useEffect(() => {
    const getProducts = async () => {
      try {
        const res = await fetch('/api/products');
        const data = await res.json();
        setProducts(data);
      } catch (err) {
        console.error(err);
      }
    };

    getProducts();
  }, []);

  return (
    <div>
      {products.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}
    </div>
  );
};

export default ProductsClient;

然后在page.tsx中引入该组件:

// src/app/page.tsx
import ProductsClient from './ProductsClient';

export default function Home() {
  return (
    <main>
      <h1>产品列表</h1>
      <ProductsClient />
    </main>
  );
}

方案2:服务器组件中使用绝对路径

通过环境变量配置base URL,在fetch时拼接成绝对路径:

  1. 在项目根目录创建.env文件:
NEXT_PUBLIC_APP_URL=http://localhost:3000

生产环境替换为你的实际域名。

  1. 修改page.tsx中的fetch逻辑:
// src/app/page.tsx
interface Product {
  id: number;
  name: string;
  // 补充你的产品字段
}

const getProducts = async () => {
  try {
    const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000';
    const res = await fetch(`${baseUrl}/api/products`);
    const data = await res.json();
    return data as Product[];
  } catch (err) {
    console.error(err);
    return [];
  }
};

export default async function Home() {
  const products = await getProducts();
  return (
    <main>
      <h1>产品列表</h1>
      {products.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}
    </main>
  );
}

方案3:直接复用API路由的业务逻辑(推荐)

服务器组件可以直接运行服务器端代码,无需通过HTTP请求调用API,直接导入数据或逻辑:

  1. 抽离产品数据到单独文件:
// src/lib/products.ts
export interface Product {
  id: number;
  name: string;
  // 补充你的产品字段
}

export const products: Product[] = [
  { id: 1, name: "产品1" },
  { id: 2, name: "产品2" },
  // 你的产品数据
];
  1. 在page.tsx中直接使用:
// src/app/page.tsx
import { products } from '@/lib/products';

export default function Home() {
  return (
    <main>
      <h1>产品列表</h1>
      {products.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}
    </main>
  );
}

内容的提问来源于stack exchange,提问作者im-mahadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:16:13