这样在管理后台里实现 403 页面实在是太优雅了
前言
403 页面通常表示无权限访问,与 404 页面代表着不同含义。而大部分管理后台框架仅提供了 404 页面的支持,但却忽略了对 403 页面的处理,有的框架虽然也有对 403 页面的处理,但处理效果却不尽人意。
那怎么样的 403 页面才是即好用,又优雅呢?
其他框架是怎么做的
1、完全不处理
不处理的结果就是无访问权限的页面大概率会进入 404 页面的逻辑。
因为这类框架通常在路由注册前就把无访问权限的路由直接剔除了,所以当用户访问了一个无访问权限的路由,对系统来说,它就是一个不存在的路由,从而进入到 404 页面。
那弊端是什么呢?那就是用户没办法区分他想访问的这个页面,到底是因为权限不够,还是地址错误,会给用户造成一定的使用困惑。
2、稍稍处理
稍稍处理的方式和第一种思路不太一样,这类框架在路由注册前并不会对路由数据做处理,而是在路由导航守卫里去判断是否有权限访问路由,如果没有权限则进入到预先注册好的 403 页面地址。
这种方案的优势在于它区分了 404 和 403 页面,因为即便是无访问权限的路由,也是真实注册到了路由实例上,只是在访问时做了鉴权和重定向。
那弊端又是什么呢?那就是用户虽然知道了当前页面无访问权限,但却看不到页面的真实地址,因为已经被重定向到 403 页面上了,用户体验稍微欠缺了一点,就像下图这样:
我是怎么做的
先稍微思考一下方案,首先刚才第一种方案剔除无访问权限的路由肯定不行,无访问权限的路由必须得注册,这样才能和 404 页面做出区分;其次第二种方案在导航守卫里做重定向也不行,不能重定向,要保证路由地址还是原来的地址,但页面要展示 403 页面的内容。
于是,方案就出来了,那就是 在路由注册前,将无访问权限的路由的 component 直接替换成 403 页面组件 不就可以了么。这么一来,路由还是那个路由,只是对应的页面组件不一样了,既区分了 404 和 403 页面,还保留 403 页面的原始路由地址。
用代码来描述大致就是:
// 原始路由数据
[{path: '/permission',component: () =>import('@/layouts/index.vue'),children: [{path: 'index',component: () =>import('@/views/list1.vue'),meta: {auth: 'admin'// 鉴权字段,如果为 admin 时则可以访问}}]}
]// 假设用户权限为 test ,处理过后的路由数据
[{path: '/permission',component: () =>import('@/layouts/index.vue'),children: [{path: 'index',component: () =>import('@/views/403.vue'), // 注意看这里,替换成了 403 页面组件meta: {auth: 'admin'}}]}
]实际效果就是这样:

可以看到,当账号从 admin 切换到 test 后,由于 test 账号不具备访问权限,所以页面显示为 403 页面,与此同时,页面的 URL 地址依旧还是原始的地址,达到了预期的效果。
这就够了么?
当然没有,因为 404 页面是通过以下方式做的兜底处理:
{path: '/:all(.*)*',component: () =>import('@/views/404.vue')
}由于它并不是一个多级路由的结构,这就导致 404 页面和 403 页面的展示有一点差别,404 页面是整页显示,403 页面是局部显示:
而我希望是能和 404 页面保持一致,也就是让 403 页面也进行整屏显示。
处理起来也不复杂,无非是在路由注册前,将无访问权限的多级路由转成一级路由就可以啦,当然处理过程会使用到递归,以及需要将多级路由的 path 进行合并,从代码来描述大致就是这样:
// 原始路由数据
[{path: '/permission',component: () =>import('@/layouts/index.vue'),children: [{path: 'index',component: () =>import('@/views/list1.vue'),meta: {auth: 'admin'// 鉴权字段,如果为 admin 时则可以访问}}]}
]// 假设用户权限为 test ,处理过后的路由数据
[{path: '/permission/index', // 注册看这里,将多级路由的 path 合并成一级component: () =>import('@/layouts/403.vue'),meta: {auth: 'admin'}}
]最终效果如下:
总结
403 页面是个重要程度并不那么高的功能,对于一般框架来说,文章一开始提到了两个方案都可以做到「让权限不足的用户禁止访问页面」的需求。
而我的方案则是在满足使用需求的前提下,尽可能优化用户体验,虽然没有提供实际的代码,但相信看到这的大家应该都能理解,可以在业务中去自行实践下。
至于优雅么?至少目前我觉得在同类产品里,还是挺优雅的😌
其他
我在研究上面第2个方案示例图里的那个框架时发现,它切换账号时不会刷新页面,体验还挺丝滑的。
当然这得益于它所选的方案,因为路由不需要随着用户权限或账号的变化而变化,所以也就不需要通过刷新页面或者重新登录的方式去更新路由。
或许我还能再优化优化,让这个方案再优雅一点?如果你有好的建议,也可以在下面留言讨论下。
相关文章:
这样在管理后台里实现 403 页面实在是太优雅了
前言403 页面通常表示无权限访问,与 404 页面代表着不同含义。而大部分管理后台框架仅提供了 404 页面的支持,但却忽略了对 403 页面的处理,有的框架虽然也有对 403 页面的处理,但处理效果却不尽人意。那怎么样的 403 页面才是即好…...
c++提高篇——STL常用算法
STL常用算法一、常用遍历算法一、for_each 遍历容器二、transform 搬运容器到另一个容器中二、常用查找算法一、find二、find_if三、adjacent_find四、binary_search五、count六、count_if三、常用排序算法一、sort二、random_shuffle三、 merage四、reverse四、常用拷贝和替换…...
Materials - DistanceField Nodes
以前的相关笔记,归档发布;距离场相关节点:DistanceToNearestSurface节点:求出传入的Position位置到最近的面的距离并输出,在没有Position输入的时候,默认值会直接使用World Position:Position的…...
【ARMv8 编程】ARMv8 指令集介绍
ARMv8 架构中引入的最重要的变化之一是增加了 64 位指令集。该指令集补充了现有的 32 位指令集架构。这种增加提供了对 64 位宽整数寄存器和数据操作的访问,以及使用 64 位长度的内存指针的能力。新指令被称为 A64,以 AArch64 执行状态执行。ARMv8 还包括…...
大数据之Phoenix基本介绍
文章目录前言一、Phoenix简介二、Phoenix入门(一)创建表语法(二)查看表信息(三)删除表(四)大小写问题前言 #博学谷IT学习技术支持# 上篇文章介绍了Phoenix环境搭建,点击…...
算法leetcode|38. 外观数列(多语言实现)
文章目录38. 外观数列:样例 1:样例 2:提示:分析:题解:rustgocpythonjava38. 外观数列: 给定一个正整数 n ,输出外观数列的第 n 项。 「外观数列」是一个整数序列,从数字…...
异步交互的关键——Ajax
文章目录1,Ajax 概述1.1 作用1.2 同步和异步1.3 案例1.3.1 分析1.3.2 后端实现1.3.3 前端实现2,axios2.1 基本使用2.2 快速入门2.2.1 后端实现2.2.2 前端实现2.3 请求方法别名最后说一句1,Ajax 概述 AJAX (Asynchronous JavaScript And XML):异步的 Jav…...
Android自定义View实现打钩签到动画
效果图实现原理我们看实现的动画效果,其实是分为1. 绘制未选中状态图形(圆弧和对号)2. 绘制选中状态圆弧的旋转的动画3. 绘制选中状态圆弧向中心收缩铺满动画4. 绘制选中状态对号5. 绘制选中状态下圆的放大回弹动画6. 暴露接口接口回调传递选…...
python+pytest接口自动化(3)-接口测试一般流程及方法
首先我们要明确,通常所接口测试其实就属于功能测试,主要校验接口是否实现预定的功能,虽然有些情况下可能还需要对接口进行性能测试、安全性测试。在学习接口自动化测试之前,我们先来了解手工接口测试怎样进行。URL组成为了更好的理…...
《MySQL学习》 表中随机取记录的方式
一.初始化测试表 创建表 words CREATE TABLE words ( id int(11) NOT NULL AUTO_INCREMENT, word varchar(64) DEFAULT NULL, PRIMARY KEY (id)) ENGINEInnoDB;插入测试数据 create procedure idata()begin declare i int; set i 0; while i<10000 do insert into words…...
功率信号源有什么作用和功能呢
功率信号源是指集信号发生器与功率放大器为一体的电子测量仪器,它具有高电压、大功率的特点,在电子实验室中能够帮助用来驱动压电陶瓷、换能器以及电磁线圈等,可以有效的帮助电子工程师解决驱动负载和放大功率的问题。功率信号源和功率放大器…...
一些cmake error fixed
建完虚拟环境后 运行 pip install . 出现报错,显示svox2安装出错,然后开始进入到svox2中进行手动编译和安装。 1. cmake svox2/csrc pybind11找不到 conda install pybind11用 pip install 在虚拟环境中安装不行,据说会安装到全局下… 2. c…...
CentOS 7安装Docker并使用tomcat测试
文章目录环境准备Docker安装安装tomcat环境准备 CentOS 7以上版本linux内核版本需要在3.10以上,可通过uname -r 查看系统内核。 Docker安装 检查docker安装源 yum list docker yum安装docker : yum install docker.x86_64 启动 docker : s…...
隐私计算头条周刊(2.20-2.26)
开放隐私计算收录于合集#企业动态45个#周刊合辑45个#政策聚焦38个#隐私计算92个#行业研究37个开放隐私计算开放隐私计算OpenMPC是国内第一个且影响力最大的隐私计算开放社区。社区秉承开放共享的精神,专注于隐私计算行业的研究与布道。社区致力于隐私计算技术的传播…...
安装kibana 报错/访问不了
安装kibana 报错1,elasticsearch.yaml 和kibana.yaml 配置问题2,elasticsearch 和kibana版本不一致3,索引问题1,elasticsearch.yaml 和kibana.yaml 配置问题 我的RPM安装的,配置文件都在/etc/ vim /etc/elasticsearc…...
【华为OD机试模拟题】用 C++ 实现 - 身高排序(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明身高排序题目输入输出示例一输入输出Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:ht…...
MK60DX256VLQ10(256KB)MK60DN256VLQ10 Kinetis K60 MCU FLASH
MK60DX256VLQ10(256KB)MK60DN256VLQ10 Kinetis K60 MCU 32BIT 256KB FLASH 144LQFP【说明】Kinetis K6x MCU系列是一个可扩展的组合,具有不同级别的集成,提供丰富的模拟、通信、定时和控制外设套件,以适应广泛的需求。应用楼宇自动化控制器人…...
Prometheus 告警模块配置深度解析
本文您将了解到Prometheus 告警模块Alertmanager 配置的深度解析 Alertmanager 配置解析 Alertmanager 配置可以用命令行配置,也可以通过配置文件配置。命令行用来配置不可变的系统参数,配置文件用来定义限制规则用于通知路由和通知接收者。 Alertmana…...
《分布式技术原理与算法解析》学习笔记Day23
分布式数据复制 我们在进行分布式数据存储设计时,通常会考虑对数据进行备份,以提高数据的可用性和可靠性,“数据复制技术”就是实现数据备份的关键技术。 什么是数据复制技术? 在分布式数据库系统中,通常会设置主备…...
毕业设计 基于51单片机的手机蓝牙控制8位LED灯亮灭设计
基于51单片机的手机蓝牙控制8位LED灯亮灭设计1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STC89C52单片机核心系统电路设计2.2 LED电路设计2.3 蓝牙模块电路设计3、部分代码展示3.1 定时器初始化以及中断处理3.2 串口初始化3.3 串口中断处理1、项目简介 选题指导&…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
