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(()=>{
    
});
複製代碼
相關文章
相關標籤/搜索