axios使用:https://juejin.cn/post/7034827130701611016
手写axios核心代码:https://juejin.cn/post/6856706569263677447
// 创建 axios 类class Axios {constructor () {// 拦截器this.interceptors = {request: new InterceptorsManage,response: new InterceptorsManage}}request(config) {// 拦截器和请求组装队列let chain = [ this.sendAjax.bind(this), undefined ] // 成对出现的,失败回调暂时不处理// 请求拦截this.interceptors.request.handlers.forEach(interceptor => {chain.unshift(interceptor.fullfield, interceptor.rejected)})// 响应拦截this.interceptors.response.handlers.forEach(interceptor => {chain.push(interceptor.fullfield, interceptor.rejected)})// 执行队列,每次执行一对,并对promise赋最新的值let promise = Promise.resolve(config)while(chain.length > 0) {promise = promise.then(chain.shift(), chain.shift())}return promise}// 封装ajaxsendAjax(config) {return new Promise(resolve => {const { url = '', method = 'get', data = {} } = config// 发送 ajax 请求const xhr = new XMLHttpRequest()xhr.open(method, url, true)xhr.onload = function () {// resolve(xhr.response)try {// 将结果转为json对象resolve(JSON.parse(xhr.response))} catch (err) {resolve(xhr.response)}}xhr.send(data)})}}// 定义get,post...方法,挂在到Axios原型上const methodsArr = ['get', 'post', 'delete', 'put', 'patch', 'options', 'head']methodsArr.forEach(met => {Axios.prototype[met] = function() {// 处理单个方法if(['get', 'delete', 'head', 'options'].includes(met)) {// 2个参数(url[, config])return this.request({method: met,url: arguments[0],...arguments[1] || {}})} else {// 3个参数(url[,data[,config]])return this.request({method: met,url: arguments[0],data: arguments[1] || {},...arguments[2] || {}})}}})// 拦截器class InterceptorsManage {constructor () {// 保存回调this.handlers = []}use(fullfield, rejected) {this.handlers.push({fullfield,rejected})}}// 工具方法,实现将b的方法混入aconst utils = {extend(a, b, context) {for (let key in b) {if (b.hasOwnProperty(key)) {if (typeof b[key] === 'function') {a[key] = b[key].bind(context)} else {a[key] = b[key]}}}}}// 最终导出axios的方法,即实例的request方法function CreateAxiosFn () {let axios = new Axios()let req = axios.request.bind(axios)// 混入方法,将Axios.prototype上的方法搬运到request上utils.extend(req, Axios.prototype, axios)// 将axios上的拦截器挂载到request上utils.extend(req, axios)return req}// 得到最后的全局变量axioslet axios = CreateAxiosFn()
