一、路由拦截
const routes = [
{
path: '/',
name: '/',
component: Index
},
{
path: '/repository',
name: 'repository',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: Repository
},
{
path: '/login',
name: 'login',
component: Login
}
];
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth) { // 判断该路由是否需要登录权限
if (store.state.token) { // 通过vuex state获取当前的token是否存在
next();
}
else {
next({
path: '/login',
query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由
})
}
}
else {
next();
}
})
每个钩子方法接收三个参数:
- to: Route: 即将要进入的目标 路由对象
- from: Route: 当前导航正要离开的路由
- next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
- next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
- next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
- next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
拦截器
axios拦截请求:首次登录的请求不带token,之后都带上token
axios拦截响应:请求时报错的部分处理封装函数
import stores from 'store'
import axios from 'axios'
import { Message } from 'element-ui'
import router from './router'
// 拦截请求
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)
}
if (stores.get('tokenData')) {
config.headers.Authorization = `Token ${stores.get('tokenData').token}`
}
// console.log(config, '响应数据')
return config
},
err => {
// console.log(err)
return Promise.reject(err)
})
// 拦截响应
axios.interceptors.response.use(
response => {
// console.log(response, '响应正确')
return response
},
error => {
// 此处报错可能因素比较多
// 1.需要授权处用户还未登录,因为路由段有验证是否登陆,此处理论上不会出现
// 2.需要授权处用户登登录过期
// 3.请求错误 4xx
// 5.服务器错误 5xx
// 关于鉴权失败,与后端约定状态码为500
console.log(error.response, '响应错误拦截')
let text = ''
if (error.response) {
text = setResponse(error.response.data)
} else {
Message.error({
message: '响应有误,请联系管理员',
duration: 1000
})
}
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 error;
// return Promise.reject(error.response.data)
})
function setResponse(jsonObj) {
for (let key in jsonObj) {
let element = jsonObj[key]
if (element.length > 0 && typeof (element) === 'object' || typeof (element) === 'object') {
// console.log(element)
setResponse(element)
} else {
arr.push(element)
}
}
return arr
}
// 注销
export function removeLogin() {
stores.remove('tokenData')//移除store里面的缓存
}