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

Vue 2出现Maximum call stack size exceeded问题求助

问题分析与修复:根据用户roles_id重定向时出现栈溢出错误

我在根据用户roles_id值重定向到对应路径时遇到问题,报错“Maximum call stack size exceeded”。使用switch语句尝试解决也无效,该问题在本地环境正常,但部署到服务器后出现。以下是我的代码:

const getUserRole = (to, from, next) => {
  const currentUser = JSON.parse(localStorage.getItem("userData"));
  if (currentUser) {
    if (currentUser.roles_id === 1 && to.name === "user-dashboard") {
      next({
        name: "dashboard-new"
      });
    } else if (currentUser.roles_id === 2 && to.name === "dashboard-new") {
      next({
        name: "user-dashboard"
      });
    } else if (currentUser.roles_id === 3 && to.name === "mails-track") {
      next({
        name: "dispatch-dashboard"
      });
    } else if (to.name === "dashboard-new" && currentUser.roles_id === 1) {
      next();
    } else if (to.name === "user-dashboard" && currentUser.roles_id === 2) {
      next();
    } else if (to.name === "dispatch-dashboard" && currentUser.roles_id === 3) {
      next();
    } else {
      next("/");
    }
  } else {
    next("/");
  }
};

export default [{
    path: "/dashboard",
    name: "dashboard-new",
    component: () =>
      import("@/views/dashboard/new/DashboardNew.vue"),
    meta: {
      requiresAuth: true
    },
    beforeEnter: (to, from, next) => {
      const currentUser = JSON.parse(localStorage.getItem("userData"));
      if (currentUser && currentUser.roles_id === 1) {
        getUserRole(to, from, next);
      } else {
        next("/");
      }
    }
  },
  {
    path: "/user-dashboard",
    name: "user-dashboard",
    component: () =>
      import("@/views/dashboard/new/user/UserDashboard.vue"),
    meta: {
      requiresAuth: true
    },
    beforeEnter: (to, from, next) => {
      const currentUser = JSON.parse(localStorage.getItem("userData"));
      if (currentUser && currentUser.roles_id === 2) {
        getUserRole(to, from, next);
      } else {
        next("/");
      }
    }
  }
];

核心问题:无限重定向循环

你的代码触发了无限重定向循环,这是栈溢出的根本原因:

  • 当roles_id=1的用户访问user-dashboard时,getUserRole会重定向到dashboard-new
  • 而dashboard-new的beforeEnter钩子中,验证用户是roles_id=1后,又调用了getUserRole
  • 虽然getUserRole中存在放行逻辑,但服务器环境下路由解析的严格性,加上重复调用守卫函数的行为,导致路由生命周期被反复触发,最终形成无限循环,耗尽调用栈

另外,代码存在冗余逻辑:路由钩子和getUserRole重复读取localStorage,且判断条件零散,容易出现逻辑漏洞。


修复方案:简化守卫逻辑,避免重复调用

优化思路

  1. 统一角色与路由的对应关系,避免零散的条件判断
  2. 移除路由钩子中的重复校验,用单一守卫函数处理所有角色路由的校验
  3. 明确逻辑分支:仅在用户访问非授权路由时重定向,否则直接放行

修复后的代码

// 统一的角色校验守卫
const checkUserRole = (to, from, next) => {
  const currentUser = JSON.parse(localStorage.getItem("userData"));
  if (!currentUser) {
    next("/");
    return;
  }

  // 定义角色与专属路由的映射
  const roleToRoute = {
    1: "dashboard-new",
    2: "user-dashboard",
    3: "dispatch-dashboard"
  };

  const allowedRouteName = roleToRoute[currentUser.roles_id];
  // 访问的是自己的专属路由,直接放行
  if (to.name === allowedRouteName) {
    next();
  } 
  // 访问了其他角色的专属路由,重定向到自己的路由
  else if (Object.values(roleToRoute).includes(to.name)) {
    next({ name: allowedRouteName });
  } 
  // 其他未知路径,重定向到首页
  else {
    next("/");
  }
};

export default [
  {
    path: "/dashboard",
    name: "dashboard-new",
    component: () => import("@/views/dashboard/new/DashboardNew.vue"),
    meta: { requiresAuth: true },
    beforeEnter: checkUserRole
  },
  {
    path: "/user-dashboard",
    name: "user-dashboard",
    component: () => import("@/views/dashboard/new/user/UserDashboard.vue"),
    meta: { requiresAuth: true },
    beforeEnter: checkUserRole
  }
];

额外说明

  • 本地环境可能因缓存或路由匹配优先级问题,暂时未触发循环,但服务器环境的路由解析逻辑更严格,导致问题暴露
  • 避免在路由守卫中嵌套调用守卫函数,每次next()都会触发路由生命周期,极易引发循环

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:35:29