什么是拦截器
拦截器就是拦截每一次的请求和响应,然后进行相应的处理。请求拦截器,它可以统一在你发送请求前在请求体里加上token;响应拦截器,是在接受到响应之后进行的一些操作,比如,服务器返回登录状态失效,需要重新登录的时候,就给它跳到登录页面;
代码没有相同的 但是思路都是一样
思路 思路 思路。。。重要的事情说三遍!!!
创建实例
axios.create({
baseURL:'http://localhost:8080', //请求的域名,基本地址
timeout:5000, //请求的超时时长,单位毫秒
url:'/data.json', //请求的路径
method:'get,post,put,patch,delete' , //请求方法
headers:{
token:'' //比如token登录鉴权,请求的时候携带token,让后端识别登录人的信息
}, //请求头
params:{}, //请求参数拼接在URL上
data:{}, //请求参数放在请求体里
})
优先级:axios请求配置 > axios实例配置 > axios全局配置
实际开发中axios全局配置一般比较少用到,因为它的局限性比较大,一般只能设置baseURL,timeout,url,其他的method,headers,params,data这些请求都是不一样的
request拦截器
// request拦截器
service.interceptors.request.use(config => {
// 如果是put/post请求,用qs.stringify序列化参数
const methodType = config.method === 'put' || config.method === 'post'
const _headers = config.headers['Content-Type'] === 'application/json'
if (methodType && _headers ) {
config.data = JSON.stringify(config.data)
}
if (methodType && !_headers ) {
config.data = qs.stringify(config.data, { arrayFormat: 'repeat' })
}
// 在请求被发送之前做的事
// 可以添加一些加载 动画。。。或者根据业务需求进行
/** 配置全屏加载 */
if (config.loading !== false) {
config.loading = Loading.service({
lock: true,
background: 'rgba(0, 0, 0, 0.7)',
spinner: 'el-icon-loading',
text: '请稍候...'
})
}
response响应
service.interceptors.response.use(
/** 响应成功发生的
* 也可以直接response.status===200判断
*/
async response => {
await closeLoading(response)
return response.data
},
// 服务器状态码不是2开头的的情况
// 这里可以跟你们的后台开发人员协商好统一的错误状态码
// 然后根据返回的状态码进行一些操作,例如登录过期提示,错误提示等等
// 下面列举几个常见的操作,其他需求可自行扩展
async error => {
await closeLoading(error)
const error_response = error.response || {}
const error_data = error_response.data || {}
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
if(error_response.status === 401) {
Vue.prototype.$message.error('身份验证失败,请关闭重新进入。')
}
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
if (error_response.status === 403) {
if (!Storage.getItem('admin_refresh_token')) return
store.dispatch('fedLogoutAction')
router.push({ path: `/login?forward=${location.pathname}` })
return
}
// 404请求不存在
if(error_response.status === 404) {
Vue.prototype.$message.error('您访问的网页不存在。')
}
if (error.config.message !== false) {
let _message = error.code === 'ECONNABORTED' ? '连接超时,请稍候再试!' : '网络错误,请稍后再试!'
Vue.prototype.$message.error(error_data.message || _message)
}
return Promise.reject(error)
}
)
/**
* 关闭全局加载
* 延迟200毫秒关闭,造成不好的视觉体验
* @param target
*/
const closeLoading = (target) => {
if (!target.config.loading) return true
return new Promise((resolve, reject) => {
setTimeout(() => {
target.config.loading.close()
resolve()
}, 200)
})
}