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),直接复用数据获取逻辑更高效,还能避免跨环境的潜在问题。
解决办法
查看正确的输出位置:
打开启动 Next.js 的终端窗口,你会发现posts的实际数据已经打印在那里。优化数据获取逻辑(推荐):
把数据获取逻辑抽成独立函数,在 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;
- 创建
若需在浏览器控制台输出(调试客户端逻辑):
给组件加上'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
相关产品推荐
相关产品推荐

