requst库源码解析(运用axios及拦截器)
创始人
2024-05-16 09:45:11

axios 用法分析

request 库使用了 axios 的手动实例化方法 create 来封装请求,要理解其中的用法,我们需要首先学习 axios 库的用法

axios 基本案例

我们先从一个普通的 axios 示例开始:

//npm i -S axios
// 在APP.vue中引入
import axios from 'axios'const url = 'https://test.youbaobao.xyz:18081/book/home/v2?openId=1234'
axios.get(url).then(response => {console.log(response)
})

上述代码可以改为:

const url = 'https://test.youbaobao.xyz:18081/book/home/v2'
axios.get(url, { 
// params 是一个对象,这个对象可以穿参数 get请求params: { openId: '1234' }
})

我们在请求时需要在 http header 中添加一个 token,需要将代码修改为:

const url = 'https://test.youbaobao.xyz:18081/book/home/v2'
axios.get(url, { params: { openId: '1234' },//  tokenheaders: { token: 'abcd' }
}).then(response => {console.log(response)
})

如果要捕获服务端抛出的异常,即返回非200请求,需要将代码修改为:

const url = 'https://test.youbaobao.xyz:18081/book/home/v2'
axios.get(url, { params: { openId: '1234' },headers: { token: 'abcd' }
}).then(response => {console.log(response)
}).catch(err => {console.log(err)
})

这样改动可以实现我们的需求,但是有两个问题:

  • 每个需要传入 token 的请求都需要添加 headers 对象,会造成大量重复代码
  • 每个请求都需要手动定义异常处理,而异常处理的逻辑大多是一致的,如果将其封装成通用的异常处理方法,那么每个请求都要调用一遍
    解决方法是 axios.create
axios.create 示例

他和 get方法 不一样 ,axios.get是一个静态方法,axios.create是一个动态方法,也就是说这个方法返回的结果是一个function,他不是有个具体的结果 ,通过axios.creat生成的方法,可以给他内置一些基础参数,比如参数的前缀部分和timeout,也就是对请求当中的固定部分先生成一个构造函数,通过request再来发起请求

下面我们使用 axios.create 对整个请求进行重构:

const url = '/book/home/v2'
const request = axios.create({baseURL: 'https://test.youbaobao.xyz:18081', //固定前缀timeout: 5000 //超时时间
})
request({ // 直接传入 同样返回promise对象url, method: 'get',params: {openId: '1234'}
})

首先我们通过 axios.create 生成一个函数,该函数是 axios 实例,通过执行该方法完成请求,它与直接调用 axios.get 区别如下:

  • 需要传入 url 参数,axios.get 方法的第一个参数是 url
  • 需要传入 method 参数,axios.get 方法已经表示发起 get 请求

为什么要用这个request ,因为他提供了拦截器的功能

axios 请求拦截器

上述代码完成了基本请求的功能,下面我们需要为 http 请求的 headers 中添加 token,同时进行白名单校验,如 /login 不需要添加 token,并实现异步捕获和自定义处理:

const whiteUrl = [ '/login', '/book/home/v2' ] // 设置白名单
const url = '/book/home/v2'
const request = axios.create({baseURL: 'https://test.youbaobao.xyz:18081',timeout: 5000
})
request.interceptors.request.use( // 有两个方法config => { // 拦截方法// throw new Error('error...') 抛出异常 测试// 找白名单里有没有  replace 将前缀换为空const url = config.url.replace(config.baseURL, '')// 如果有就返回if (whiteUrl.some(wl => url === wl)) {return config}// 如果没有就把headers 加上tokenconfig.headers['token'] = 'abcd'return config},error => { // 异常处理方法return Promise.reject(error)}
)
request({url, method: 'get',params: {openId: '1234'}
}).catch(err => {console.log(err)
})

这里核心是调用了 request.interceptors.request.use 方法,即 axios 的请求拦截器,该方法需要传入两个参数,第一个参数是拦截器方法,包含一个 config 参数,我们可以在这个方法中修改 config 并且进行回传,第二个参数是异常处理方法,我们可以使用 Promise.reject(error) 将异常返回给用户进行处理,所以我们在 request 请求后可以通过 catch 捕获异常进行自定义处理

axios 响应拦截器

下面我们进一步增强 axios 功能,我们在实际开发中除了需要保障 http statusCode 为 200,还需要保证业务代码正确,上述案例中,我定义了 error_code 为 0 时,表示业务返回正常,如果返回值不为 0 则说明业务处理出错,此时我们通过 request.interceptors.response.use 方法定义响应拦截器,它仍然需要2个参数,与请求拦截器类似,注意第二个参数主要处理 statusCode 非 200 的异常请求,源码如下:

const whiteUrl = [ '/login', '/book/home/v2' ]
const url = '/book/home/v2'
const request = axios.create({baseURL: 'https://test.youbaobao.xyz:18081',timeout: 5000
})
request.interceptors.request.use(config => {const url = config.url.replace(config.baseURL, '')if (whiteUrl.some(wl => url === wl)) {return config}config.headers['token'] = 'abcd'return config},error => {return Promise.reject(error)}
)request.interceptors.response.use(response => {const res = response.dataif (res.error_code != 0) {alert(res.msg)return Promise.reject(new Error(res.msg))} else {return res}},error => {return Promise.reject(error)}
)request({url, method: 'get',params: {openId: '1234'}
}).then(response => {console.log(response)
}).catch(err => {console.log(err)
})

request 库源码分析

有了上述基础后,我们再看 request 库源码就非常容易了

const service = axios.create({baseURL: process.env.VUE_APP_BASE_API, //取配置文件当中的urltimeout: 5000
})service.interceptors.request.use(config => {// 如果存在 token 则附带在 http header 中if (store.getters.token) {config.headers['X-Token'] = getToken()}return config},error => {return Promise.reject(error)}
)service.interceptors.response.use(response => {const res = response.dataif (res.code !== 20000) {Message({message: res.message || 'Error',type: 'error',duration: 5 * 1000})// 判断 token 失效的场景if (res.code === 50008 || res.code === 50012 || res.code === 50014) {// 如果 token 失效,则弹出确认对话框,用户点击后,清空 token 并返回登录页面MessageBox.confirm(message:'Token 以失效,是否重新登录',title:'确认登出',options:{confirmButtonText: '重新登录',cancelButtonText: '取消',type: 'warning'}).then(() => {store.dispatch('user/resetToken').then(() => {location.reload()})})}return Promise.reject(new Error(res.message || 'Error'))} else {return res}},error => {Message({message: error.message,type: 'error',duration: 5 * 1000})return Promise.reject(error)}
)export default service

Vue admin
登陆流程
界面精简及路由处理(实现了权限控制)
路由和权限校验原理
侧边栏
重定向
面包屑导航
requst库 axios拦截
登录组件实现细节

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
少数民族的传统节日有哪些 55... 公务员考试常识判断模块考查范围广泛,需要大家在日常多加积累,本文小编总结了中国少数民族的传统节日,希...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
mb什么意思 MB和Mb 相信很多人都还不太清楚手机流量的统计单位,经常听说谁谁流量包月5个G。其实G、GB、KB、M和MB数...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...