请求拦截.响应拦截
// 导入 axios
import axios from 'axios'
// 导入组件库
import { Loading } from 'element-ui'
import router from '../router/index'
// 全局挂载axios
axios.defaults.baseURL = 'http://www.liulongbin.top:3008'
// 全局挂载 - 请求拦截器
let fullScreenLoading
axios.interceptors.request.use(function (userinfo) {
if (userinfo.url.startsWith('/my')) {
userinfo.headers.Authorization = localStorage.getItem('token')
}
// 展示 loading 效果
fullScreenLoading = Loading.service({
text: '拼命加载中',
fullscreen: true,
background: 'rgba(0, 0, 0, 0.8)'
})
return userinfo
}, function (error) {
return Promise.reject(error)
})
// 全局挂载 - 响应拦截器
axios.interceptors.response.use(function (response) {
// 隐藏 loading 效果
fullScreenLoading.close()
return response
}, function (error) {
// 响应失败会进入当前函数
// 如果本地token过期.则删除
// 如果响应状态码是 401,则强制跳转到登录页面
if (error.response.status === 401) {
localStorage.removeItem('token')
router.push('/login')
}
// 隐藏 loading 效果
return Promise.reject(error)
})
// 导出axios
export default axios
import axios from 'axios'
import { Message } from 'element-ui'
import Store from '../store'
import Router from '../router'
const _axios = axios.create({
baseURL: process.env.VUE_APP_BASE_API
})
// 请求拦截
_axios.interceptors.request.use(
config => {
if (Store.state.user.token) {
config.headers.Authorization = `Bearer ${Store.state.user.token}`
console.log(`Bearer ${Store.state.user.token}`, '请求头')
}
return config // 成功
},
// Promise 返回数据
error => {
return Promise.reject(error) // 错误
})
// 响应拦截
_axios.interceptors.response.use(res => {
// 成功处理提示信息
if (res.data.success) {
return res.data
} else {
// 错误信息提示
Message.error(res.data.message)
// 这里是promise方法的失败执行结果
return Promise.reject(res.data.mesaage)
}
},
error => {
// 当出现token失效的时候会报错401
// 做一个401的统一拦截处理.
// 1.清除token
// 2.清除用户信息
// 3.提示错误信息
// 4.跳转至登录页面
if (error.response && error.response.status === 401) {
// Store.commit('user/setToken', '')
// Store.commit('user/setUserinfo', '')
Store.commit('user/logout')
Message.error(error.response.data.message)
// 路由传参 当规则校验判断提示401或者token失效过时时.
// 通过拿到 整段路径然后使用#分割截取第二部分.
Router.push('/login?abcdefg=' + window.location.href.split('#')[1])
}
return Promise.reject(error)
})
export default _axios
导航守卫
// 前置导航守卫
import router from './router'
import Store from './store'
// 用来模拟加载页面进度条,并不是真的加载.
// 下包
// 导入+css样式
// 使用
// NProgress.start()
// NProgress.done()
// 模拟加载进度条
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// 设置白名单.不需要验证就可以访问的路径
// const whiterr = ['/login', '/404']
// 前置守卫 to去哪 from从哪来 next放行通过
router.beforeEach(async(to, from, next) => {
NProgress.start()
// 唯一出口next
// 通过判断是否有token
// 如果有.再判断去哪里.
// 当有token的时候如果去的是登录页面或者其他页面则直接默认出口为/ 默认页面.
// 但是只是有token容易被人携带非正确token混入.那么需要再次判断唯一值.
// 否则如果有ID则通过去默认页面
// 没有ID则自动调用发起请求获取ID.再去默认页面.
// 者个时候.因为发起的请求是异步任务.会延迟执行.那么它后面的代码会先执行.所以我们需要await来设置阻塞.等待异步任务完成. await必须配合async一起使用
if (Store.state.user.token) {
//这里设置的是判断字体大小写.
if (to.path.toLowerCase() === '/login') {
next('/')
} else {
// 当有token的同时是否获取到了id如果有就放行
if (Store.state.user.userinfo.userId) {
next()
} else {
//否则没有id则再次发起请求重新获取数据
await Store.dispatch('user/sysuserinfo')
next()
}
}
// 当没有token的时候默认等于没有登录.那么通过白名单访问登录页面.或者404
} else {
// tolowerCase解决输入接口的大小写问题
// if (whiterr.includes(to.path.toLowerCase())) {
// next()
// }
// 使用路由原的时候.通过自定义方式
// 在路由中设置meta:{noLogin=true 为白名单.} 默认是false
if (to.meta.noLogin) {
next()
} else {
// 设置退出或者重新登录时回跳到原来页面.
next('/login?abcdefg=' + to.fullPath)
}
}
// 这是一个模拟加载页面的效果
// 有nprogress.start 请求进度条
// nprogress.done 完成进度条.
NProgress.done()
})
// 后置导航守卫
router.afterEach(() => {
NProgress.done()
})