Next.js 13构建报错:location未定义,如何实现localstorage鉴权跳转?
解决Next.js客户端组件鉴权时
location is not defined的问题 问题根源
你当前的代码在组件初始化阶段(可能处于服务端渲染/静态生成流程)就执行了router.push,即便标记了'use client',组件的顶层逻辑仍会在服务端被执行,而服务端不存在location对象,因此触发报错。另外,useState初始值为null,useEffect要等客户端挂载后才会触发,导致顶层的if (!auth)判断会在服务端提前执行跳转逻辑。
修正方案
方案1:将鉴权与跳转逻辑移至useEffect内
确保所有依赖浏览器环境的操作只在客户端执行:
'use client' import { useRouter } from 'next/router'; import { useState, useEffect } from 'react'; const AdminPage = () => { const router = useRouter(); const [auth, setAuth] = useState<string | null>(null); useEffect(() => { const checkAuth = () => localStorage.getItem('auth'); const authToken = checkAuth(); setAuth(authToken); if (!authToken) { router.push('/admin/login'); } }, [router]); // 鉴权未完成时返回加载占位 if (auth === null) { return <div>加载中...</div>; } return <div>管理员页面内容...</div>; }; export default AdminPage;
方案2:用状态控制渲染流程
通过状态标记鉴权状态,避免服务端执行跳转逻辑:
'use client' import { useRouter } from 'next/router'; import { useState, useEffect } from 'react'; const AdminPage = () => { const router = useRouter(); const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null); useEffect(() => { const authToken = localStorage.getItem('auth'); if (!authToken) { router.push('/admin/login'); setIsAuthenticated(false); } else { setIsAuthenticated(true); } }, [router]); // 鉴权未完成或未通过时,不渲染页面内容 if (isAuthenticated !== true) { return null; // 可替换为加载组件 } return <div>管理员页面内容...</div>; }; export default AdminPage;
额外注意事项
- 禁止在组件顶层直接调用依赖浏览器环境的API(如
localStorage、router.push),务必放到useEffect或其他客户端生命周期钩子内。 - 仅靠客户端鉴权存在安全漏洞,必须在服务端同步做权限校验(比如接口请求时验证token有效性),防止用户绕过客户端限制直接访问敏感页面。
内容的提问来源于stack exchange,提问作者user19297279
相关产品推荐
相关产品推荐

