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

NextJS路由处理器直接访问正常,控制台调用返回空对象求助

Next.js API 路由返回数据正常,但页面组件中获取后输出空对象

我在 /api/posts/route.js 中定义了如下 API 路由,用来获取 JSONPlaceholder 的数据:

export async function GET() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const data = await res.json();

  return Response.json({ data: data });
}

直接在浏览器访问 http://localhost:3000/api/posts 时,能正常看到完整的 JSON 数据,说明 API 路由功能没问题。

但在 /posts/page.jsx 中调用该 API 并尝试打印数据时,控制台只输出空对象,页面代码如下:

import React from 'react';

export async function getPosts() {
  const res = await fetch('http://localhost:3000/api/posts');

  const data = await res.json();

  return data.data;
}

const Post = async () => {
  const posts = await getPosts();
  console.log(posts);
  return (
    <div>
      <h1>Hello</h1>
    </div>
  );
};

export default Post;

请问这是什么原因?


问题原因

在 Next.js App Router 中,page.jsx 默认是服务器组件。服务器组件中的 console.log 不会输出到浏览器控制台,而是输出到启动 Next.js 的终端窗口里。你看到的浏览器控制台空对象,是混淆了输出位置导致的误解。

另外,服务器组件中调用内部 API 路由完全没必要走网络请求(http://localhost:3000/api/posts),直接复用数据获取逻辑更高效,还能避免跨环境的潜在问题。

解决办法

  1. 查看正确的输出位置:
    打开启动 Next.js 的终端窗口,你会发现 posts 的实际数据已经打印在那里。

  2. 优化数据获取逻辑(推荐):
    把数据获取逻辑抽成独立函数,在 API 路由和页面组件中复用,无需走网络请求:

    • 创建 lib/fetchPosts.js:
      export async function fetchPosts() {
        const res = await fetch('https://jsonplaceholder.typicode.com/posts', {
          cache: 'no-store' // 根据业务需求配置缓存策略
        });
        if (!res.ok) {
          throw new Error('获取帖子数据失败');
        }
        return res.json();
      }
      
    • 修改 /api/posts/route.js:
      import { fetchPosts } from '@/lib/fetchPosts';
      
      export async function GET() {
        const data = await fetchPosts();
        return Response.json({ data });
      }
      
    • 修改 /posts/page.jsx:
      import { fetchPosts } from '@/lib/fetchPosts';
      
      const Post = async () => {
        const posts = await fetchPosts();
        console.log(posts); // 输出将显示在终端
        return (
          <div>
            <h1>帖子列表</h1>
            <ul>
              {posts.map(post => (
                <li key={post.id}>{post.title}</li>
              ))}
            </ul>
          </div>
        );
      };
      
      export default Post;
      
  3. 若需在浏览器控制台输出(调试客户端逻辑):
    给组件加上 'use client' 指令转为客户端组件,结合 useEffect 和状态管理处理异步请求:

    'use client';
    import React, { useEffect, useState } from 'react';
    
    const Post = () => {
      const [posts, setPosts] = useState([]);
    
      useEffect(() => {
        const getPosts = async () => {
          const res = await fetch('/api/posts'); // 客户端可使用相对路径
          const data = await res.json();
          setPosts(data.data);
          console.log(data.data); // 此时会输出到浏览器控制台
        };
        getPosts();
      }, []);
    
      return (
        <div>
          <h1>Hello</h1>
        </div>
      );
    };
    
    export default Post;
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:22:16