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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:05:04