最近在学习Vue2,遇到有些页面请求数据须要用户登陆权限、服务器响应不符预期的问题,可是总不能每一个页面都作单独处理吧,因而想到axios提供了拦截器这个好东西,再因而就出现了本文。vue
路由导航钩子全部配置均在router/index.js,这里是部分代码ios
import Vue from 'vue'
import Router from 'vue-router'
import { getUserData } from '@/script/localUserData'
const MyAddress = r => require.ensure([], () => r(require('@/views/MyAddress/MyAddress')), 'MyAddress')
Vue.use(Router)
const routes = [
{
path: '/profile/address',
name: 'MyAddress',
component: MyAddress,
meta: {
title: '个人地址',
requireAuth: true
}
},
// 更多...
]
const router = new Router({
mode: 'history',
routes
})复制代码
咱们主要来看下面逻辑处理部分的代码git
let indexScrollTop = 0
router.beforeEach((to, from, next) => {
// 路由进入下一个路由对象前,判断是否须要登录
// 在路由meta对象中由个requireAuth字段,只要此字段为true,必须作鉴权处理
if (to.matched.some(res => res.meta.requireAuth)) {
// userData为存储在本地的一些用户信息
let userData = getUserData()
// 未登陆和已经登陆的处理
// getUserData方法处理后若是userData.token没有值就是undefined,下面直接判断
if (userData.token === undefined) {
// 执行到此处说明没有登陆,君可按需处理以后再执行以下方法去登陆页面
// 我这里没有其余处理,直接去了登陆页面
next({
path: '/login',
query: {
redirect: to.path
}
})
} else {
// 执行到说明本地存储有用户信息
// 可是用户信息是否过时仍是须要验证一下滴
let overdueTime = userData.overdueTime
let nowTime = +new Date
// 登录过时和未过时
if (nowTime > overdueTime) {
// 登陆过时的处理,君可按需处理以后再执行以下方法去登陆页面
// 我这里没有其余处理,直接去了登陆页面
next({
path: '/login',
query: {
redirect: to.path
}
})
} else {
next()
}
}
} else {
next()
}
if (to.path !== '/') {
indexScrollTop = document.body.scrollTop
}
document.title = to.meta.title || document.title
})
router.afterEach(route => {
if (route.path !== '/') {
document.body.scrollTop = 0
} else {
Vue.nextTick(() => {
document.body.scrollTop = indexScrollTop
})
}
})
export default router复制代码
至此,路由钩子层面的鉴权处理完毕,不过细心的你可能注意到:导航去登陆页面调用的next方法里面有个query对象,携带了目标路由的地址,这是由于在登陆成功后咱们须要重定向到目标页面。github
axios全部配置均在件script/getData.js文件,这里是本文件公共代码部分vue-router
import qs from 'qs'
import { getUserData } from '@/script/localUserData'
import router from '@/router'
import axios from 'axios'
import { AJAX_URL } from '@/config/index'
axios.defaults.baseURL = AJAX_URL复制代码
axios请求拦截器代码axios
/**
* 请求拦截器,请求发送以前作些事情
*/
axios.interceptors.request.use(
config => {
// POST || PUT || DELETE请求时先格式化data数据
// 这里须要引入第三方模块qs
if (
config.method.toLocaleUpperCase() === 'POST' ||
config.method.toLocaleUpperCase() === 'PUT' ||
config.method.toLocaleUpperCase() === 'DELETE'
) {
config.data = qs.stringify(config.data)
}
// 配置Authorization参数携带用户token
let userData = getUserData()
if (userData.token) {
config.headers.Authorization = userData.token
}
return config
},
error => {
// 此处应为弹窗显示具体错误信息,由于是练手项目,劣者省略此处
// 君可自行写 || 引入第三方UI框架
console.error(error)
return Promise.reject(error)
}
)复制代码
axios响应拦截器代码后端
/**
* 响应拦截器,请求返回异常统一处理
*/
axios.interceptors.response.use(
response => {
// 这段代码不少场景下没用
if (response.data && response.data.success === false) {
// 根据实际状况的一些处理逻辑...
return Promise.reject(response)
}
return response
},
error => {
// 此处报错可能因素比较多
// 1.须要受权处用户还未登陆,由于路由段有验证是否登录,此处理论上不会出现
// 2.须要受权处用户登登陆过时
// 3.请求错误 4xx
// 5.服务器错误 5xx
// 关于鉴权失败,与后端约定状态码为500
switch (error.response.status) {
case 403:
// 一些处理...
break
case 404:
// 一些处理...
break
case 500:
let userData = getUserData()
if (userData.token === undefined) {
// 此处为未登陆处理
// 一些处理以后...再去登陆页面...
// router.push({
// path: '/login'
// })
} else {
let overdueTime = userData.overdueTime
let nowTime = +new Date
if (overdueTime && nowTime > overdueTime) {
// 此处登陆过时的处理
// 一些处理以后...再去登陆页面...
// router.push({
// path: '/login'
// })
} else {
// 极端状况,登陆未过时,可是不知道哪儿错了
// 按需处理吧...我暴力回到了首页
router.push({
path: '/'
})
}
}
break
case 501:
// 一些处理...
break
default:
// 状态码辣么多,按需配置...
break
}
return Promise.reject(error)
}
)复制代码
想了解更多关于axios的信息?请移步这里。bash
这个封装很简单,面对复杂的业务确定还须要更多的考量,可是对于通常的小项目或边缘业务也差很少够用了。最后但愿这篇文章能对有须要的同窗提供一些帮助。服务器