axios原理

axios是一个基于promise的http请求库,可用于浏览器和node。
const axios=require('axios')
axios.defaults.baseURL = 'http://xxx.com/api'
axios.interceptors.request.use(resolveFn1, rejectFn2)
axios.interceptors.response.use(resolveFn2, rejectFn2)
添加请求拦截器 添加响应拦截器

axios.get('/get').then(()=>{}, )

createInstance返回一个axios实例(axios.create也可以创建axios实例,
内部也是调用createInstance

createInstance
//./lib/axios.js
function createInstance(defaultConfig){
  //根据默认设置 新建一个axios对象
  var context=new Axios(defaultConfig)

  //axios中所有的请求[axios,axios.get,axios.post等……]内部都是调用的
  Axios.prototype.request,见[./code/Axios.js]

  //将Axios.prototype.request的内部this绑定上新建的axios对象上
  从而形成一个axios实例
  var instance = bind(Axios.prototype.request, context)

  utils.extend(instance, Axios.prototype, context)
  将Axios.prototype属性添加到instance

 

content====》新建Axios对象
Axios.prototype.request(其内部this绑定到新建的Axios对象上)
[axios,axios.get,axios.post 都是调用Axios.prototype.request]
形成instance=axios实例
Axios.prototype属性添加

首先内部会新建一个Axios对象,Axios对象结构函数如下
function Axios(instanConfig){
  this.defaults=instanceConfig      一些默认设置项
  this.interceptors={
    request: new InterceptorManager()  //request拦截器
    response: new InterceptorManager()  //response拦截器
  }
}

新建的axios对象主要用来挂载axios实例的一些设置(如defaults
会挂载axios实例的通用设置,interceptors用于存放拦截器)

axios实例是对axi内部的this绑定到新建的os.prototype.request方法包裹了一层函数,
主要是将axios。prototype。request内部的this绑定到新建的axios

通过utils.extend将内部context和Axios.prototype
最终的axios实例上面的内部的this指向的都是新建的axios对象


对每个axios实例设置不同config

因为axios内部调用的都是axios.prototype.request方法
axios.prototype.request默认请求方法为get。为了让开发者可以直接axios
(config)就可以发送get
}  

Axios.prototype.request
见./lib/core/Axios
Axios.prototype.request=function request(config){
  if(typeof config==='string'){
    config=utils.merge({
      url:arguments[0]
    }, arguments[1]);
  }
 进行配置项的合并 优先级:Axios默认的defaults  <调用时axios请求方法时传入的condig

 config=utils.merge(defaults,{
  method:'get'
 }, this.defaults, config)
 config.method=config.method.toLowerCase()

  var chain=[dispatchRequest, undefined]  //dispatchRequest封装了对于
  发起ajax的逻辑处理

  var promise=Promise.resolve(config)

  var promise=Promise.resolve(config)

  //request拦截器的执行顺序是:先加入后执行
  this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor))
  {
    chain.unshift(interceptor.fulfilled,interceptor.rejected)
  }}
  //而response拦截器是:先加入的先执行
  this.interceptors.response.forEach(function pushResponseInterceptors){
    chain.push(interceptor.fulfilled,interceptor.rejected)
  }
 
  request.interceptor2=>request.interceptor1=>[dispatchRequest,undefined]=>
  response.interceptor1=>response.interceptor2
  内部通过promise.then形成promise链,从而将chain中拦截器的调用串联起来,
  dispatchRequest是对ajax请求发起的封装实现,也会返还一个promise对象
  while(chain.langth){
    promise=promise.then(chain.shift(),chain.shift())
  }

  return promise

  Axios.prototype.request内部会进行了一些配置项的合并工作
  变量chain相当于一个任务队列
  以2个为一组存放任务(1个是任务成功回调,1是任务失败回调,通过
  不断调用promise.then方法形成一个promise链
 
  执行顺序示例:
  request.interceptor用于请求发起前的准备工作(可以修改data和headers

  response.interceptor用于服务器返回数据后的处理工作(也是对data处理,
  整个请求的发起过程通过dispatchRequest实现的

  dispatchRequest
  function dispatchRequest(config){
  依次调用transformRequest数组中的函数对data、headers进行处理,
  方便在向服务器发送请求之前对data和headers进行修改(例如对data
  进行编码加密等

  config.data=transformData(
    config.data,
    config.headers,
    config.transformRequest
  );

  return adapter(config).then(
    function onAdaptRequest(response)
  )
  }
*/
/*
1.
vue不支持发送ajax请求,要用vue-resource(1.0)\axios(2.0)
跨域:
vue-resource:
this.$http.get\head\delete\jsonp(url,[options])
this.$http.post\put\patch(url,[body],[options])
axios不支持跨域,第三方

2.axios基于promise的用于浏览器和nodejs的http请求客户端,本质上也是对原生XHR的封装
原理:

axios(const axios=require('axios'))来自createInstance,
(顾名思义,创建实例, return instance;),
内部新建一个Axios对象,
axios/axios.get/axios.post……都来自Axios.prototype.request
用bind把Axios.prototype.request内部this绑定到Axios对象上,形成
一个axios实例
然后返回这个instance

3.为什么不将所有方法在Axios上实现然后返回new Axios呢?
Axios.prototype.request默认请求方法为get。
为了可以直接axios(config)就可以发送get请求,而不需要axios.get(config)


4.Axios.prototype.request
(我知道)内部有配置项的合并,dispatchRequest封装了发起ajax(整个请求过程的发起过程)
(还有)request拦截器(先加入后执行,用于请求发起前的准备工作) 和
response拦截器(先加入的先执行,用于服务器返回数据之后的处理工作),

5.dispatchRequest
transformData(config.data, config.headers, config.transformRequest)是为了向服务器发送请前对 data 进行处理
return adapter(适配器模式,对不同环境做了适配处理,根据config发送请求然后返回一个promise,promise的状态根据请求的结果来决定)

你可能感兴趣的:(axios原理)