项目中,有些页面须要登陆后才能进入,例如,在某页面A,用户在操做前须要先进入登陆页(此时须要将上一页的地址(/survey/start
)做为query存入login页面的地址中,如: http://localhost:8071/#/login?redirect=%2Fsurvey%2Freport
),登陆成功后再进入页面A。css
首先,在router.js中建立路由时,给须要登陆的路由中的 meta 添加字段:requireLogin,以下:html
const router = new Router({ routes: [ { path: '/login', name: 'Login', component: Login, meta: { title: '登陆页' } }, { path: '/register', name: 'Register', component: Register, meta: { title: '注册页' } }, { path: '/', redirect: '/survey/start', name: 'Full', component: Full, children: [ { path: '/survey/start', name: 'Home', component: Home, meta: { title: '首页', requireLogin: true } }, { path: '/survey/report', name: 'Report', component: Report, meta: { title: '详情页', requireLogin: true } } ] } ] })
而后使用 router.beforeEach 注册一个全局前置守卫:前端
// 全局导航钩子 router.beforeEach((to, from, next) => { if (to.meta.title) { // 路由发生变化修改页面title document.title = to.meta.title } if (to.meta.requireLogin) { if (store.state.token) { if (Object.keys(from.query).length === 0) { // 判断路由来源是否有query,处理不是目的跳转的状况 next() } else { let redirect = from.query.redirect // 若是来源路由有query if (to.path === redirect) { // 避免 next 无限循环 next() } else { next({ path: redirect }) // 跳转到目的路由 } } } else { next({ path: '/login', query: { redirect: to.fullPath } // 将跳转的路由path做为参数,登陆成功后跳转到该路由 }) } } else { next() } })
关于Vue Router导航守卫,参考:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E5%89%8D%E7%BD%AE%E5%AE%88%E5%8D%ABvue
上面的方法只是进行了前端拦截,没法肯定存储在本地的token是否已经失效。须要 axios 拦截器:ios
在mian.js 中:axios
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import Axios from 'axios' import './assets/styles/reset.css' import './plugins/element.js' import htmlToPdf from './utils/htmlToPdf' Vue.config.productionTip = false Vue.use(htmlToPdf) // http request 拦截器 Axios.interceptors.request.use( config => { if (sessionStorage.getItem('token')) { // 若存在token,则每一个Http Header都加上token config.headers.Authorization = `token ${sessionStorage.getItem('token')}` } return config; }, err => { return Promise.reject(err); }) // http response 拦截器 Axios.interceptors.response.use( response => { return response; }, error => { if (error.response) { switch (error.response.status) { case 401: // 返回 401 (未受权) 清除 token 并跳转到登陆页面 sessionStorage.removeItem('token') router.replace({ path: 'login', query: { redirect: router.currentRoute.fullPath } }) } } return Promise.reject(error.response.data) // 返回接口返回的错误信息 } ) new Vue({ router, store, render: h => h(App) }).$mount('#app')