一、问题复现
使用axios响应拦截器代码重定向到login登录页面
/* 响应拦截器 */ axios.interceptors.response.use(function (response) { // ①10010 token过期(30天) ②50000000 token无效 if (response.data.code === 50000000) { window.localStorage.removeItem('token') window.localStorage.removeItem('activePath') router.replace({ path: '/login' // 到登录页重新获取token }) } else if (response.data.token) { // 判断token是否存在,如果存在说明需要更新token window.localStorage.setItem('token', response.data.token) // 覆盖原来的token(默认一天刷新一次) } return response }, function (error) { return this.$message.error(error) })
二、报错如下:
Uncaught runtime errors:
×
ERROR
Navigating to current location ("/login") is not allowed
Error
at new NavigationDuplicated (webpack-internal:///./node_modules/vue-router/dist/vue-router.esm.js:2024:14)
at HashHistory.confirmTransition (webpack-internal:///./node_modules/vue-router/dist/vue-router.esm.js:2140:18)
at HashHistory.transitionTo (webpack-internal:///./node_modules/vue-router/dist/vue-router.esm.js:2084:8)
at HashHistory.replace (webpack-internal:///./node_modules/vue-router/dist/vue-router.esm.js:2525:10)
at eval (webpack-internal:///./node_modules/vue-router/dist/vue-router.esm.js:2840:22)
at new Promise (<anonymous>)
at VueRouter.replace (webpack-internal:///./node_modules/vue-router/dist/vue-router.esm.js:2839:12)
at _router__WEBPACK_IMPORTED_MODULE_1__.default.beforeEach.document.title (webpack-internal:///./src/main.js:78:53)
at async Axios.request (webpack-internal:///./node_modules/axios/lib/core/Axios.js:49:14)
at async VueComponent.getMenuList (webpack-internal:///./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/views/Home/Home.vue?vue&type=script&lang=js:59:11)
三、错误原因
1、该错误是Vue-Router在3.1.0+版本中引入Promise API后出现的常见问题,当重复导航到相同路由路径时触发
2、版本机制变更:Vue-Router 3.1.0+版本中,router.push或router.replace会返回Promise对象,若未捕获重复导航的异常,则会在控制台显示该错误
3、重复导航:在登录页面(/login)尝试再次跳转到相同路径时,触发了路由保护的重复导航限制
四、解决方法
捕获路由跳转异常,修改拦截器代码,使用.catch捕获重复导航错误:
router.replace({ path: '/login' }).catch(err => {});
五、完整代码
axios.interceptors.response.use(function (response) { if (response.data.code === 50000000) { window.localStorage.removeItem('token'); window.localStorage.removeItem('activePath'); router.replace({ path: '/login' }).catch(err => {}); } else if (response.data.token) { window.localStorage.setItem('token', response.data.token); } return response; }, function (error) { return this.$message.error(error); });
文章评论(0)