Vue Router的beforeEach钩子在Safari浏览器不触发该如何处理?
vue-router 的全局前置守卫 beforeEach 本身完全兼容 Safari 浏览器,不存在官方不支持的情况,你遇到的钩子不触发问题属于配置、依赖兼容性或者代码逻辑问题,以下是常见的排查方向和解决方法:
- 排查 cookie 相关逻辑的兼容性问题
Safari 的 cookie 安全策略比 Chrome 严格得多,对跨域 cookie、第三方 cookie、过期时间异常的 cookie 都会做限制,旧版本的vue-cookies包也存在 Safari 下的兼容问题。你可以先注释掉VueCookies.get('jwtToken')相关代码,只保留控制台打印语句,测试钩子是否能正常触发。如果注释后可以正常打印,说明是 cookie 获取逻辑抛出隐式错误中断了钩子执行,可以升级vue-cookies到最新稳定版,或者改用localStorage存储 token 验证。 - 检查路由守卫的注册顺序
必须保证router.beforeEach的注册逻辑在app.use(router)(Vue3)或者new Vue({router})(Vue2)之前执行。不同浏览器的模块加载顺序有差异,如果你的守卫注册代码写在异步加载的模块中,Safari 下可能出现路由实例已经挂载完成后才注册守卫的情况,导致守卫不会生效。 - 检查路由跳转的触发方式
只有通过router.push、router.replace、<router-link>等 vue-router 提供的方式触发的路由跳转才会触发全局守卫,如果你使用原生a标签跳转、直接修改location.href或者调用location.replace跳转,低版本 Safari 不会触发路由守卫逻辑。 - 补全 next 调用的边界逻辑
你当前的代码存在一处逻辑遗漏:当未登录用户访问需要鉴权的 login 路由时,没有调用next()。虽然你配置了 login 路由不需要鉴权,不会走到这个分支,但如果配置出错就会出现逻辑死锁,Safari 下这种死锁会直接终止钩子执行且不会抛出可见错误。可以按下方代码补全逻辑:if(!isAuthenticated) { if(to.name != 'login') { next({name: 'login'}); } else { next(); // 补全未登录访问登录页时的next调用 } } - 升级 vue-router 到稳定版本
如果你使用的是 vue-router 3.x 版本低于 3.6.5、或者 4.x 版本低于 4.1.6,存在已知的 Safari 下守卫触发异常的 bug,直接升级到对应大版本的最新稳定版即可解决。
内容的提问来源于stack exchange,提问作者Ghunhee Shin
相关产品推荐
相关产品推荐

