Vue导航守卫无法拦截切屏、复制粘贴等页面内行为,仅控制路由跳转;切屏检测依赖visibilitychange事件及blur/focus回退,复制粘贴需document原生事件监听,beforeunload与守卫协同防误关页。

Vue 导航守卫本身不能直接拦截切屏或复制粘贴这类浏览器底层行为——它只控制路由跳转,而切屏、粘贴、右键等发生在当前页面内,不触发路由变化。真正起作用的是浏览器原生 API 与 Vue 组合式逻辑的配合,导航守卫只在其中承担“辅助拦截”和“兜底提交”的角色。
切屏检测靠 visibilitychange,不是 router.beforeEach
用户切换标签页、最小化窗口、切换应用时,页面会进入 hidden 状态。这是 Page Visibility API 的职责范围:
- 监听
document.addEventListener('visibilitychange', ...),判断document.hidden是否为 true - 配合 ref 记录切换次数,达到阈值(如 3 次)后主动调用
router.push('/submit')或触发考试提交事件 - 注意:iOS Safari 和部分微信内置浏览器对 visibilitychange 支持有限,需 fallback 到
blur/focus事件组合判断
导航守卫用于防止“主动跳转”类作弊
当考生试图手动输入新 URL、点击外部链接、或通过 history API 跳转时,router.beforeEach 才真正生效:
- 检查 to.path 是否为白名单路径(如 '/exam'、'/result'),否则
next(false)中断跳转 - 结合考试状态(如
isExamStarted.value && !isExamSubmitted.value)做条件拦截 - 可配合 localStorage 标记“考试进行中”,跳转前校验该标记是否存在且有效
复制粘贴与右键禁用,需全局事件监听
这些行为完全绕过 Vue 路由系统,必须在组件 onMounted 中绑定原生事件:
立即学习“前端免费学习笔记(深入)”;
document.addEventListener('copy', e => e.preventDefault())document.addEventListener('contextmenu', e => e.preventDefault())document.addEventListener('cut', e => e.preventDefault())- 建议封装为 composable(如
useAntiCheatEvents()),在考试组件中统一调用
页面卸载前拦截,靠 beforeunload + 路由守卫双保险
防止误刷新或关闭导致数据丢失,同时增强威慑力:
- 在考试开始时设置
window.onbeforeunload = () => '考试未提交,确定要离开?' - 在
router.beforeEach中检查目标路由是否为非考试路径,若正在考试中则弹出确认提示 - 注意:现代浏览器已限制
beforeunload自定义文案,仅显示统一提示;真正强制交卷需依赖服务端超时或前端定时上报心跳


















