axios principle

1: Learn about axios

Basic concepts:
axios is an HTTP client based on promise for browsers and Node.js, or axios is an asynchronous Ajax request Library Based on promise
Features: (gitHub has a detailed introduction)

2: axios principle

  In essence, Axios is the function returned by Axios.prototype.request function bind(). In terms of function, Axios can be an instance of Axios prototype
  Axios has all the methods and properties on the Axios prototype. Let's analyze the workflow of Axios from the perspective of source code (rough analysis)
//Create a new instance of axios
function createInstance(defaultConfig) {
  var context = new Axios(defaultConfig);
  var instance = bind(Axios.prototype.request, context);

  // Copy axios.prototype to instance
  //Bind the methods of the Axios prototype object to the new instance (axios)
  utils.extend(instance, Axios.prototype, context);
  
  // Copy context to instance
  //Add properties on the Axios prototype to the new instance (axios) interceptors and default configuration (default)
  utils.extend(instance, context);

  return instance;
}

// Create axios with default configuration
var axios = createInstance(defaults);

From the above source code, we can see that Axios is the function returned by Axios.prototype.request function bind(). In this case, what's in Axios

Provide alias for request method
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
  /*eslint func-names:0*/
  Axios.prototype[method] = function(url, config) {
    return this.request(utils.merge(config || {}, {
      method: method,
      url: url
    }));
  };
});

utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
  /*eslint func-names:0*/
  Axios.prototype[method] = function(url, data, config) {
    return this.request(utils.merge(config || {}, {
      method: method,
      url: url,
      data: data
    }));
  };
});
request() function
Axios.prototype.request = function request(config) {
  /*eslint no-param-reassign:0*/
  // Allow for axios('example/url'[, config]) a la fetch API
  if (typeof config === 'string') {
    config = arguments[1] || {};
    config.url = arguments[0];
  } else {
    config = config || {};
  }

  config = mergeConfig(this.defaults, config);

  // Set config.method
  if (config.method) {
    config.method = config.method.toLowerCase();
  } else if (this.defaults.method) {
    config.method = this.defaults.method.toLowerCase();
  } else {
    config.method = 'get';
  }

  // Hook up interceptors middleware
  var chain = [dispatchRequest, undefined];
  var promise = Promise.resolve(config);

  this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
	 //Request interceptor head insertion, completed successful callback, rejected failed callback
    chain.unshift(interceptor.fulfilled, interceptor.rejected);
  });

  this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
	  //Response interceptor tail append, completed successful callback, rejected failed callback
    chain.push(interceptor.fulfilled, interceptor.rejected);
  });

  while (chain.length) {
    promise = promise.then(chain.shift(), chain.shift());
  }
  return promise;
};

In the request function, use promise to concatenate the callback / dispatchRequest / response interceptor of the request interceptor. This makes it logical to execute the sequential request interceptor - > send request - > response interceptor. This also explains why the order of execution is reversed when we add request interceptors. Because promise uses a header append when it concatenates request interceptors. Since there's no request anywhere else, let's go to dispatchRequest again

  module.exports = function dispatchRequest(config) {
  throwIfCancellationRequested(config);

  // Ensure headers exist
  config.headers = config.headers || {};

  // Transform request data
  //Transform request data
  config.data = transformData(
    config.data,
    config.headers,
    config.transformRequest
  );

  // Flatten headers
  config.headers = utils.merge(
    config.headers.common || {},
    config.headers[config.method] || {},
    config.headers
  );

  utils.forEach(
    ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
    function cleanHeaderConfig(method) {
      delete config.headers[method];
    }
  );

  var adapter = config.adapter || defaults.adapter;

  return adapter(config).then(function onAdapterResolution(response) {
    throwIfCancellationRequested(config);

    // Transform response data
    response.data = transformData(
      response.data,
      response.headers,
      config.transformResponse
    );

    return response;
  }, function onAdapterRejection(reason) {
    if (!isCancel(reason)) {
      throwIfCancellationRequested(config);

      // Transform response data
      if (reason && reason.response) {
        reason.response.data = transformData(
          reason.response.data,
          reason.response.headers,
          config.transformResponse
        );
      }
    }

    return Promise.reject(reason);
  });
};

It mainly processes the request data before the request is initiated / the Adapter sends the request / processes the response data after the request is initiated
In that case, let's take a look at the Adapter
There are several statements

......
var request = new XMLHttpRequest();
......
request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
......
request.send(requestData);

It's cleared up here. axios actually encapsulates ajax

summary
The working principle and process of axios are as follows:

3: Other content

**

axios and Instance:

Instance is the instance object created by axios.create()
Same point:
Instance and axios can send any request (get/post...)
There are ways to send specific requests
Both have default configuration and interceptor configuration
Difference:

axios.create = function create(instanceConfig) {
	//mergeConfig merge
  return createInstance(mergeConfig(axios.defaults, instanceConfig));
};

The configuration of Instance and axios is different (the exception is that the config parameter is empty)
Instance has no new properties and methods of axios, such as create(), CancelToken(),all(),Axios
Instance did not cancel request and wholesale request

Why use Instance:
Multiple interfaces in the project have different configurations. Create two new instance s, each with its own configuration. This is a good solution

Don't spray, big man, little white

Published 2 original articles, praised 0 and visited 21
Private letter follow

Tags: axios github

Posted on Thu, 13 Feb 2020 23:17:06 -0800 by calevans