Next.js中使用getServerSideProps获取数据库数据时,为什么页面刷新后数据丢失?
我在Next.js项目里用getServerSideProps调用MongoDB API获取用户数据,首次加载正常显示,但手动刷新页面时突然报错说user是undefined,这到底是怎么回事?
尝试过:getServerSideProps里用axios请求/api/users端点,服务端能正常返回数据,但控制台报错说无法读取user.name属性。错误发生在:function UserPage({ user }) { return
{user.name}
}这里
export async function getServerSideProps() {
const res = await axios.get('/api/users/123')
return {
props: {
user: res.data // 这里返回的是包含_id、name等字段的对象
}
}
}
检查过API端点没问题,Postman测试能正常返回用户对象,但页面刷新时为什么props突然变成空值?是不是和SSG/SSR缓存有关?
/api/users/123接口,但你可能没意识到这个请求在 SSR 中并不是你想象的那样工作的。当你用
axios.get('/api/users/123'),你发的是一个相对路径的请求。在客户端运行没问题,但getServerSideProps是在服务端执行的,这时候/api路径并不存在,Node.js 环境里当然找不到你本地启动的那个 API 服务,所以实际请求失败了,但你没处理错误,导致res.data是 undefined,传给页面的user就是空的。控制台报错说
user.name是因为user根本没传进来。你应该直接连接数据库取数据,而不是调用/api接口。如果你坚持要在这个阶段调接口,应该改成完整的 URL:
http://localhost:3000/api/users/123,但更推荐的做法是,在getServerSideProps里直接引入你的数据库模型,比如用 mongoose 的User.findById('123'),避免多余的 HTTP 请求。另外,
getServerSideProps返回的props必须是 JSON 兼容的数据,如果你传的是 mongoose 的 doc,记得.toObject()或者.lean()转成 plain object,不然也会静默失败。总之,别在 SSR 里调本地
/api接口,直接查数据库更稳。getServerSideProps里调用的 API 路径不对导致的。注意看这句:
你这里用的是相对路径
/api/users/123,在客户端运行没问题,但在 **服务端** 运行时,axios发起的请求是发给 **Node.js 服务器自己**,不是浏览器当前页面的 origin。也就是说,你本地开发时,前端是localhost:3000,而getServerSideProps里面发的/api/users/123会被解析成http://localhost:3000/api/users/123,而不是你预期的后端 API 地址。刷新页面时报
user is undefined,说明res.data根本就没拿到数据,可能是返回了 404 或 500,但你没处理错误,最后传给页面的user是undefined。---
### 解决方案
你应该使用**绝对路径**来调用外部 API,比如:
或者,如果你的 API 和 Next.js 项目在同一台服务器上,可以这样写:
---
### 安全提醒
另外,注意安全:不要在
getServerSideProps中暴露敏感信息或直接透传用户输入,防止 SSRF、注入等攻击。建议加上错误处理:然后在页面中判断
user === null,提示错误或重定向。---
总结:你遇到的是 SSR 环境下请求路径解析错误导致的接口失败,和缓存无关。换成绝对 URL,加上错误处理就解决了。