路由拦截

项目中,有些页面需要登录后才能进入,例如,在某页面A,用户在操作前需要先进入登录页(此时需要将上一页的地址(/survey/start)作为query存入login页面的地址中,如: http://localhost:8071/#/login?redirect=%2Fsurvey%2Freport),登录成功后再进入页面A。

首先,在router.js中创建路由时,给需要登录的路由中的 meta 添加字段:requireLogin,如下:

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%AB

axios 请求拦截

上面的方法只是进行了前端拦截,无法确定存储在本地的token是否已经失效。需要 axios 拦截器:

在mian.js 中:

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')

最新文章

  1. Python之路第一课Day9--随堂笔记之一(堡垒机实例以及数据库操作)未完待续....
  2. ASCIITable: 演示 Arduino 串口输出的进阶功能
  3. INI文件的读取(C语言:GetPrivateProfileString/GetPrivateProfileInt)
  4. DOM--3 DOM核心和DOM2 HTML(1)
  5. laravel captcha
  6. Select的深入应用(2)
  7. java中HashMap的用法
  8. 如何诊断oracle数据库运行缓慢或hang住的问题
  9. mysql 时间戳与日期格式的相互转换
  10. Android应用开发学习之AlertDialog对话框
  11. 转: ajax跨域之JSONP
  12. ASP.NET MVC 5 学习教程:Details 和 Delete 方法详解
  13. ionic 项目中创建侧边栏的具体流程分4步简单学会
  14. Scrum Meeting Alpha - 6
  15. Android查缺补漏--Activity生命周期和启动模式
  16. 【RL-TCPnet网络教程】第32章 RL-TCPnet之Telnet服务器
  17. [Swift]LeetCode147. 对链表进行插入排序 | Insertion Sort List
  18. Python内置函数(23)——format
  19. webpack代理解决跨域问题
  20. eclipse 工作区空格和回车键显示为乱码

热门文章

  1. 使用Chrome开发者工具远程调试原生Android上的H5页面
  2. 5.1Python函数(一)
  3. 【软件工程1916|W(福州大学)_助教博客】团队答辩助教问题记录
  4. 为什么MySQL数据库索引选择使用B+树?
  5. Django之知识总结
  6. swift语言混编--语言交互的接口
  7. [TJOI2010]分金币
  8. 离线安装Cloudera Manager 5和CDH5(最新版5.9.3) 完全教程(四)数据库安装(单节点)
  9. solvepnp
  10. ubuntu RPLIDAR A2的使用