场景:我们在做项目时,肯定是需要封装我们的请求函数,不然每个页面都得写一遍,麻烦不说,而且需要改请求域名或者公共属性的话,就得一个个去改,比较麻烦,所以我们需要将共同的方法封装起来
具体代码及注释如下:
创建如下路径的文件:src/utils/request.js
// 基于axios 封装,网络请求的函数
// 第一步:导入axios
import axios from 'axios'
// 因为在统一添加请求头Authorization里的值是token,这个token是从vuex里获取的,所以需要引入vuex
import store from '@/store'
import router from '../router'// (因为这不是组件,所以本身不能使用router.push跳转路由,所以需要引入router)
import { Message } from 'element-ui'// 按需导入elementui的弹框组件
// 第二步
// axios.create()创建一个带配置项的自定义axios函数
// myAxios请求的时候,地址baseUrl+url,然后去请求后台
const myAxios = axios.create({
baseURL: 'http://这是请求地址。。。.net'
})
// 第三步:定义请求拦截器
// api里每次调用request都会先走这个请求拦截器
myAxios.interceptors.request.use((config) => {
// config配置对象(要请求后台的参数都在这个对象上)
// 在请求前会触发一次,这个return交给axios源码内,根据配置项发起请求
// 在发起请求时,统一携带请求头Authorization和touken值
// 判断:登录页/注册页,vuex无token,而且这两个页面也不需要携带token(其他页面需要)
if (store.state.token) { // 判断如果store中的token有值的话,才去添加
config.headers.Authorization = store.state.token
}
return config
}, (error) => {
// 请求前发起的代码,如果有异常报错,会直接进入这里、
// 返回一个拒绝状态的Promise对象(axios留在原地的Promise对象状态就为失败结果为error变量值)
// 次函数类似catch函数()里的return
// 口诀:return非Promise对象值,会作为成功的结果,返回给下一个Promise对象(axios留在原地)
// 口诀:returnPromise对象,这个Promise对象状态,返回给下一个Promise对象
// Promise.reject()原地留下个新的Promise对象(状态为失败)它是Promise的类方法reject()简写
return Promise.reject(error)
// 等同于直接把错误信息返回出去
})
// 定义服务器响应拦截器(为了判断登录信息是否过期),拦截器必须是:interceptors.response标准
myAxios.interceptors.response.use((response) => {
// 响应http状态码为2xx或3xx,触发成功的回调,形参中 res 是“成功的结果”
// 这个结果会return到axios原地Promise对象,作为成功的结果
return response
}, (error) => {
console.dir('服务响应错误拦截信息:', error)
// 响应状态码不是2xx时,4xx,5xx触发失败回调,形参中的error是“失败的回调”
// 这个错误信息会return到axios原地Promise对象位置,作为失败拒绝的状态(如果那边用try+catch或者catch函数捕获,可以捕获到我们传递过去的这个error变量的值)
if (error.response.status === 401) { // 本次响应是token过期了
// 清楚vuex里一切,然后切换回到登录页面(被动退出登录状态)
store.commit('updateToken', '')// 传空值
store.commit('updataUserInfo', {})// 传空字符串
Message.error('用户身份已过期!!!')
router.push('/login')// 跳转到登录页(因为这不是组件,所以本身不能使用router.push跳转路由,所以需要在上面引入router)
}
return Promise.reject(error)
})
// 第四步:导出axios自定义函数
export default myAxios