Node.js应用中客户端仅获取2条服务端数据的问题排查
问题:Next.js客户端仅获取到服务端返回的2条数据,而非全部3条
服务端代码(Node.js + Express)
const express = require('express'), server = express(), cors = require('cors'); server.use(cors({origin: "http://localhost:3000"})); server.get('/json-data', (req, res) => { res.status(200).send([ {order:10,value:29}, {order:100,value:541}, {order:1000,value:7919}]) }); server.listen(8888);
直接访问http://localhost:8888/json-data可确认服务端返回完整的3条数据数组。
客户端正常场景(带'use client'标记的组件)
'use client' function Receiver() { fetch("http://localhost:8888/json-data") .then(res => res.json()) .then(data => { console.log('Receiver-0:'+JSON.stringify(data[0])) console.log('Receiver-1:'+JSON.stringify(data[1])) console.log('Receiver-2:'+JSON.stringify(data[2])) }) return( <div> <h1>Hello Receiver !!</h1> </div> ) }
浏览器显示Hello Receiver !!,控制台能打印出全部3条数据。
客户端异常场景(无'use client'标记的异步组件)
代码1
async function Receiver() { const response = await fetch("http://localhost:8888/json-data"); const primes = await response.json(); const data = JSON.stringify(primes) return <h1>{data}</h1>; } export default Receiver;
代码2(Next.js官方文档风格)
async function getData() { const res = await fetch('http://localhost:8888/json-data') if (!res.ok) { throw new Error('Failed to fetch data') } return res.json() } export default async function Receiver() { const data = await getData() return <main>{JSON.stringify(data)}</main> }
上述两种代码运行后,浏览器仅显示:
[{"order":10,"value":29},{"order":100,"value":541}]
仅展示2条数据,缺失第三条。
疑问
- 为何异步组件中仅能获取到2条数据?
- 如何修改代码让客户端获取到服务端返回的全部3条数据?
补充:客户端组件引入方式
import Receiver from './components/receiver' export default function Home() { return ( <main className="flex min-h-screen flex-col items-center justify-between p-24"> <div> <Receiver /> </div> </main> ) }
解决方案
核心原因
无'use client'标记的异步组件默认是Next.js服务器组件,此时fetch请求在服务端执行,Next.js默认会缓存fetch的响应结果。如果之前服务端曾返回过仅2条数据的响应,缓存会被复用,导致后续请求无法获取最新的3条数据。
具体解决方法
- 禁用
fetch缓存
修改异步组件中的fetch请求,添加缓存配置强制获取最新数据:
async function getData() { const res = await fetch('http://localhost:8888/json-data', { cache: 'no-store' // 禁用缓存,每次请求都获取最新数据 }) if (!res.ok) { throw new Error('Failed to fetch data') } return res.json() } export default async function Receiver() { const data = await getData() return <main>{JSON.stringify(data)}</main> }
- 将组件标记为客户端组件
给异步组件添加'use client'标记,让fetch在浏览器端执行,规避服务端缓存影响:
'use client' async function Receiver() { const response = await fetch("http://localhost:8888/json-data"); const primes = await response.json(); const data = JSON.stringify(primes) return <h1>{data}</h1>; } export default Receiver;
- 清除Next.js缓存
开发模式下,可重启Next.js开发服务器,或手动删除项目根目录下的.next文件夹,清除旧缓存后重新运行项目。
内容的提问来源于stack exchange,提问作者Michel
相关产品推荐
相关产品推荐

