防止直接修改url地址导致路由跳转

1,565 阅读2分钟

前言

前几天优化了老项目:刷新后保持当前页、菜单栏保持激活展开状态。如果手动输入路由再回车也可以进行跳转,这就会带来一个严重问题:我们项目是分角色的,不同角色有不同菜单,比如人事有人事的菜单,财务有财务的菜单,在权限没有做完善的情况下,人事直接输入财务的地址是可以看到财务的页面信息,下面纯前端方式解决这个问题。

解决方案

老项目是Vue2.x,所以我们在路由守卫里面拦截即可,如果是React其实方法也差不多,可以在入口文件写逻辑代码。

利用window.performance.navigation.type

 performance.navigation.type 该属性返回一个整数值,表示网页的加载来源,可能有以下4种情况:

  • 0:网页通过点击链接、地址栏输入、表单提交、脚本操作等方式加载
  • 1:网页通过“重新加载”按钮或者location.reload()方法加载
  • 2:网页通过“前进”或“后退”按钮加载
  • 255:任何其他来源的加载
// 路由守卫登录鉴权
router.beforeEach(function (to, from, next) {
  if (localStorage.getItem("Token")) {
    next()
    // 判断是否根据修改地址栏进行的跳转
    let reloadType = null;
    try {
      reloadType = window.performance.navigation.type;
    } catch (err) {
      reloadType = 1;
    }
    if (reloadType === 0 && !from.name && to.path !== "/home") {
      console.error("非法改变路由");
      next('/home') // 跳转到首页
    }
  } else {
    next('/')
  }
})

代码解释: 已经登录后,判断页面刷新type是否为0 路由来源是否存在(路由守卫from是来源,如果是直接刷新或者修改url来的 from对象里面值会是空的) 不是跳转到首页(这层随意)。如果满足以上条件就证明是直接修改url触发的路由跳转,直接next到首页地址就行。

扩展

另一种解决方式是在入口文件写个路由监听(不推荐) :因为滞后了页面切换,实际上已经转到了目标页调取了目标页的接口,再被转到首页的,代码如下:

  watch: {
    $route: {
      immediate: true,
      handler(to, from) {
        // 页面刷新类型
        let reloadType = null;
        try {
          reloadType = window.performance.navigation.type;
        } catch (err) {
          reloadType = 1;
        }
        if (reloadType === 0 && !from && to.path !== "/home") {
          this.$router.push({
            path: "/home",
          });
          console.error("非法改变路由");
        }
      },
    },
  },