axios源码

axios源码
匡思进两个流程参考图
一个是我写的 【Xmind思维导图】axios源码
一个是.学长写的 【Xmind思维导图】Axios https://app.xmind.cn/share/oWnkR6z1?xid=4ubuXhXS
来自 .学长
数据流
axios 作为方法导出,接收 defaults 默认配置
axios 自带 .create 方法,用户在二次封装时用到,传入一个 config 配置对象
两个方法通过 createInstance 被创造,不过 .create 方法传入的是 (mergeConfig(defaults, config)) 深合并后的默认配置
createInstance 方法中,首先创建一个 Axios 实例(即 context),然后定义一个 instance 函数,将 instance 内部的 request 方法的 this 指向 context(Axios) 实例,所以 instance(config) 等价于 Axios.request(config);
并使用 extend 浅拷贝将 context(Axios) 将实例上的所有属性方法都拷贝到 instance 方法上,最终实现:
axios(config) 等价于 axios.request(config)
axios.get / axios.post 等可用
axios.defaults / axios.interceptors 可访问
接着看 Axios 类,内部的方法主要分刚才的 request(核心) 和 get/put/post 等请求方法,请求方法内部会调用 request
request 方法接收两个参数 url,config,但一般情况下我们只传入一个参数(url || 配置对象),都会作为 url 来被传入,所以 request 内部的第一个逻辑就是判断 url/config 并归位;
第二步,创建一个 Promise 执行链(chain),初始值为 [dispatchRequest, undefined];dispatchRequest是一个函数,内部调用 xhr,负责发起请求
第三步,从 this.interceptors.request/response 中获取请求/响应拦截器,以 [onFulfilled,onRejected] 的形式插入到 chain 链的首/尾端 (请求拦截器插到开头,响应插到末尾)
第四步,使用 while 遍历 chain 链,取出拦截器配置,使用 promise 处理
最后,return promise
有关 dispatchRequest 方法,内部分三步
第一步是调用 processConfig 对配置进行标准化处理(如合并 baseURL + url,规范化 headers,转换 data 等);
第二步 xhr 适配处理,传入 config,并返回一个 Promise
第三步当适配器 resolve 响应后,使用 transformResponse 对响应数据进行转换(如解析 JSON)
最后构造最终的 response 对象并 resolve
有关 xhr 方法
第一步先解构出 url / data / headers / method / responseType / timeout 五个变量
第二步实例化一个 XMLHttpRequest 对象为 request
第三步判断 responseType / timeout 是否存在,如果存在就直接赋值到 request
第四步调用 request 的 open 方法,传入 method / url / 异步:true,在传入 method 的同时将 method 值转为大写
第五步遍历 headers 的所有属性,如果 data 为 null 且属性名为 content-type 则删除 headers 的属性名,否则处理 headers 赋值给 request
内部还实现的三个方法
request 的 onerror,reject
request 的 ontimeout,reject
request 的 onreadystatechange (readyState发生变化时自动调用),先判断 readyState 的值非 4 return,4 则继续进行(请求已完成),接着看 status 为 0 则 return (网络错误/跨域失败/取消请求),非 0 继续,这时取出所有头信息,接着处理响应数据 Data,设定完最终 response 后就可以 resolve 了





