axios源码分析--浏览器端xhr

axios源码分析--请求流程传送门ios

axios源码分析--拦截器传送门`git

源码分析

Axios.prototype.request的chain中,调用了dispatchRequest方法github

function dispatchRequest(config) {
    //...
    var adapter = config.adapter || defaults.adapter;
    return adapter(config).then(function onAdapterResolution(response) {
        ...
    }), function onAdapterRejection(reason) {
        ...
    });
}
复制代码

adapter来自defaults.adapter,咱们到axios/lib/defaults.js看看adapteraxios

var defaults = {
  adapter: getDefaultAdapter(),
  //...
}

function getDefaultAdapter() {
  var adapter;
  if (typeof XMLHttpRequest !== 'undefined') {
    adapter = require('./adapters/xhr'); //浏览器环境
  } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
    adapter = require('./adapters/http');
  }
  return adapter;
}
复制代码

浏览器环境调用xhr进入到axios/lib/adapters/xhr.js文件中api

function xhrAdapter(config) {
    return new Promise(function dispatchXhrRequest(resolve, reject) {
        //...header的一些设置
        var request = new XMLHttpRequest();
        //...验证
        //构建url
        var fullPath = buildFullPath(config.baseURL, config.url);
        request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
        
        //超时设置
        request.timeout = config.timeout;
        //
        request.onreadystatechange = function(){
            ...
            settle(resolve, reject, response)
        }
        request.onabort = function(){...}
        request.onerror = fucntion(){...}
        request.ontimeout = fucntion(){...}
        //...添加xsrf header
        //...添加请求头设置
        //...添加withCredentials的设置
        //...添加响应类型的设置
        //...添加上传和下载进度条的监听
        //...监听取消请求
        if (requestData === undefined) {
            requestData = null;
        }
        //发送请求
        request.send(requestData);
    });
}
复制代码

xhrAdapter方法返回一个promisepromise

function settle(resolve, reject, response) {
  var validateStatus = response.config.validateStatus;
  if (!validateStatus || validateStatus(response.status)) {
    resolve(response);
  } else {
    reject(createError(
      'Request failed with status code ' + response.status,
      response.config,
      null,
      response.request,
      response
    ));
  }
};
复制代码

能够配置validateStatus方法进行状态验证,根据该方法的返回值来执行resolve或者reject浏览器

axios('https://api.github.com/users/mzabriskie', {
        validateStatus: function (status) {
            return status >= 200 && status < 300; // default
        },
    }
).then(()=>{
    
}).catch(()=>{
    
});
复制代码