乐趣区

axios使用和源码阅读

axios.interceptors

axios.interceptors 拦截器主要用来作什么?和路由拦截有什么区别

一个是接口的 request,response 数据处理
一个是对业务处理,比如页面权限控制

axios 拦截
import axios from ‘axios’
import env from ‘@/env’
import Utils from ‘@/components/Utils’
import {
Message
} from ‘element-ui’

// 获取系统 ID
const systemId = Utils.getQueryString(‘systemId’)

if (systemId) {
window.systemId = systemId
} else {
// 没有系统 ID
location.href = env.dataCloud
}

const auth = (response) => {
// 未登录
if (response && ((response.status === 401) || (response.status === 412))) {
location.href = env.dataCloud
}
}

const instance = axios.create({
baseURL: `${env.api}${env.prefix.develop}`,
params: {
systemId
},
withCredentials: true
})
instance.nterceptors.response.use((response) => {
auth(response)
if (response && response.data && response.data.statusCode !== ‘0’) {
Message.error((response.data && response.data.msg) || response.data.errmsg || ‘ 抱歉 ’)
return Promise.reject(response).catch(() => {})
}
return Promise.resolve(response.data)
}, (error) => {
let msg = ‘ 网络错误, 请稍后再试 ’
if (error && error.response && error.response.status === 401) {
msg = ‘ 请登录 ’
}
const notice = document.getElementsByClassName(‘ivu-message-error’)
if (notice.length === 0) {
Message.error(msg)
}
auth(error && error.response)
return Promise.reject(error).catch(() => {})
})

export default instance

路由拦截
login.js

main.js
axios/lib/core/Axios.jsaxios/lib/core/InterceptorManager.js
拦截器上有 request,response。分别用于拦截发送,接收。
经典场景
比如这样一个场景:
在进行敏感操作 (常见敏感操作如购买,获取列表等) 之前,每个请求需要携带 token, 但是 token 有有效期,token 失效后需要换取新的 token 并继续请求。
需求分析:
每个请求都需要携带 token,所以我们可以使用 axios request 拦截器,在这里,我们给每个请求都加 token, 这样就可以节省每个请求再一次次的复制粘贴代码。token 失效问题,当我们 token 失效,我们服务端会返回一个特定的错误表示,比如 token invalid,但是我们不能在每个请求之后去做刷新 token 的操作呀,所以这里我们就用 axios response 拦截器,我们统一处理所有请求成功之后响应过来的数据,然后对特殊数据进行处理,其他的正常分发。
功能实现
在 main.js 注册 axios
jsVue.use(Vuex)
Vue.use(VueAxios, axios)
Vue.use(qs)
注:qs,使用 axios,必须得安装 qs,所有的 Post 请求,我们都需要 qs, 对参数进行序列化。

在 request 拦截器实现

axios.interceptors.request.use(
config => {
config.baseURL = ‘/api/’
config.withCredentials = true // 允许携带 token , 这个是解决跨域产生的相关问题
config.timeout = 6000
let token = sessionStorage.getItem(‘access_token’)
let csrf = store.getters.csrf
if (token) {
config.headers = {
‘access-token’: token,
‘Content-Type’: ‘application/x-www-form-urlencoded’
}
}
if (config.url === ‘refresh’) {
config.headers = {
‘refresh-token’: sessionStorage.getItem(‘refresh_token’),
‘Content-Type’: ‘application/x-www-form-urlencoded’
}
}
return config
},
error => {
return Promise.reject(error)
}
)
// 在 response 拦截器实现

axios.interceptors.response.use(
response => {
// 定时刷新 access-token
if (!response.data.value && response.data.data.message === ‘token invalid’) {
// 刷新 token
store.dispatch(‘refresh’).then(response => {
sessionStorage.setItem(‘access_token’, response.data)
}).catch(error => {
throw new Error(‘token 刷新 ’ + error)
})
}
return response
},
error => {
return Promise.reject(error)
}
)
参考
vue-axios interceptors(拦截器)实际应用一个项目学会前端实现登录拦截

退出移动版