我们平时开发项目中,并不是所有的路由都可以直接访问,有些路由需要登录之后才可以查看,这里就需要在跳转时进行一个判断,如果已经登录则直接跳转,否则跳转到登录页。通过全局导航守卫实现,即router.beforeEach
      这并没有结束,本地可能存在登录信息,但可能出现信息过期的可能。这样进行数据请求时应该跳转到登录页,这里就需要在每次的数据请求时增加一个判断。

一、axios拦截器介绍及使用

axios拦截器在每一次数据请求前和请求后进行相应的处理。下面介绍axios如何使用:
1、安装

npm install axios

2、main.js引入

import axios from 'axios'
Vue.prototype.$axios = axios

3、在main.js使用

// 添加请求拦截器
axios.interceptors.request.use(
   config => {
    // 在发送请求之前做些什么
	   console.log('在发送请求之前触发')//示例代码
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
	console.log('响应数据成功触发')//示例代码
    return response;//返回相应的数据
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

拦截器的简单实用如上,每一次axios请求都会先后触发以上两个拦截器。具体应用后面叙述

二、路由跳转拦截

前面说到了每次路由跳转前都要进行判断是有需要登录权限。那么我们在定义路由的时候需要添加一个字段gorouter,用于判断。

const routes = [
  {
	path: '/login',
	name: 'login',
	component: Login,
  },
  {
    path: '/',
    name: 'home',
    component: Home,
  	meta:{
		 app:true,
	  }
  },
  {
    path: '/about',
    name: 'about',
    component: About,
	meta:{
	     app:true,
		 gorouter:true,//需要权限
	 }
  },
  {
    path: '/news',
    name: 'news',
    component: News,
	meta:{
		  gorouter:true,//需要权限
	  }
  },
]
   



const router = new VueRouter({
  // mode: 'hash',
  base: process.env.BASE_URL,
  routes
})

router.beforeEach((to,from,next) => {
   if(to.meta.gorouter){  //判断该路由是否需要权限
	  if(store.state.token){  //判断store是否有登录信息,存储在token字段
			next()
	  }else{
			next({
				path:'/login',
				query:{redirect:to.fullPath}  //将该路由path传入login页面,登陆成功后跳转到该页面
			 })
	  }
   }else{
		next()
   }
})

to: Route: 即将要进入的目标 路由对象

from: Route: 当前导航正要离开的路由

next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航

说明:
每次路由跳转前都会执行router.beforeEach,首先判断路由中的字段gorouter,如果不存在则不需要登录则直接跳转。对需要跳转的路由再次检查,在vuex中是否存在登录信息store.state.token,如没有则将准备进入的路由to.fullPath作为query的参数传入Login,登录成功后跳转到该页面。
store官方传送门

三、axios拦截器token验证

前言:
一个完整的token验证大致分为以下几步
1、前端用户登录成功后,后端发送一个token信息(一般包含过期时间、uid等信息)反馈给前端
2、前端得到token并存入vuex,本地存储(localStroge)
3、用户进行路由跳转时,判断该路由是否需要登录权限,如果需要,则检查vuex是否含有token。
4、每一次数据请求都触发拦截器,在请求头加入token,交给后端判断。
5、后端验证请求是否含有token信息,或者token时是否过期,并返回相应的错误状态码(比如401、404等)
6、前端得到错误代码进行相应处理,如果成功则更新token

1、请求拦截

// 添加请求拦截器
axios.interceptors.request.use(
   config => {
	     if(store.state.token){//添加token信息在请求中
	   		  config.headers.Authorization = store.state.token
	   	 }  
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

这样每一次请求都会加上token信息交给后端判断

下面我们测试一下是否添加成功
模拟发送一个数据请求,给一个测试的token信息

axios.interceptors.request.use(
   config => {
	   	config.headers.Authorization = 'sfrbafhwtb' 
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

效果:

axios 参数过滤空值 axios过滤器_axios 参数过滤空值

可以看到,测试的token信息成功添加到请求头中

2、响应拦截

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
		if(response.status === 200){ //成功状态码200
		    store.state.token = response.data.data.body.token //更新token
            return response;    //返回响应的数据
		}else{
			  return  Promise.reject(response)  
		}
  }, function (error) {
    // 对响应错误做点什么
		if(error.response.status){
			switch(error.response.status){
				//未登录,跳转到登录页并携带当前页路径,登录成功后跳转
				case 401:
				    router.replace({
							path:'/login',
							query:{redirect:router.currentRoute.fullPath}
						})
				//token过期,对用户提示然后清除本地token再跳转
				case 403:
				    Toast({
							message:'登陆过期',
							duration:1000,
						})
						localStorage.removeItem('token')
						store.commit('token')
						setTimeout(() => {
							  router.replace({
								  path:'/login',
								  query:{redirect:router.currentRoute.fullPath}
							  })
						},1000)
				//请求不存在		
				case 404:
						Toast({
							message:'请求不存在',
							duration:1000,
						})
				break
				
				//其他错误,提示错误
				default:
						Toast({
					    message:error.response.data.message,
					    duration:1000,
				    })
			}
		}
    return Promise.reject(error);
  });

结语:
以上就是一个基础版的拦截器token验证,如有错误欢迎大家指正。