One. What is Axios?
A compact, easy to use, and efficient code wrapper library for managing HTTP requests based on Promise. In layman’s terms, it’s a front-end alternative to Ajax, and you can use it to initiate HTTP requests. It’s based on Promises and can manage asynchronous operations better than Ajax callback functions.
2. Axios features
Install Axios
Install it by using the NPM command.
npm i axios --saveCopy the code
2. After the installation, go to the axios file directory and check the directory structure.
Iv. Axios source code analysis
Package. json, the main field in package.json, whose value (a relative path) represents the entry file of the package. Here you can see that the entry file for the axios package is the index.js file. Look at the package scripts to execute the script, and then you can execute the script locally for debugging.
2, [Axios/axios.js] enter the entry file, you can see that Axios internal logic is in the lib folder.
[Axios/lib/axios.js] go to the Axios file, see what is exported, and then look forward based on the exported content.
module.exports = axios; Copy the code
[Axios/lib/axios.js] [Axios/lib/axios.js]
function createInstance(defaultConfig) {
var context = newAxios(defaultConfig); . return instance; }var axios = createInstance(defaults);Copy the code
Axios is the value returned by defaultConfig in createInstance.
[Axios/lib/defaults.js] [Axios/lib/defaults.js]
// Use process in nodeJS and XMLHttpRequest in the browser to distinguish between function in the front-end and nodeJS
getDefaultAdapter() {
var adapter;
if (typeofprocess ! = ='undefined' && Object.prototype.toString.call(process) === '[object process]') {
adapter = require('./adapters/http');
} else if (typeofXMLHttpRequest ! = ='undefined') {
adapter = require('./adapters/xhr');
}
return adapter;
}
var defaults = {
adapter: getDefaultAdapter(),
...
timeout: 0.xsrfCookieName: 'XSRF-TOKEN'.xsrfHeaderName: 'X-XSRF-TOKEN'.maxContentLength: - 1.validateStatus: function validateStatus(status) {
return status >= 200 && status < 300; }}; defaults.headers = {common: {
'Accept': 'application/json, text/plain, */*'}};Copy the code
As you can see from the above, axios can be used both on the client side and in the browser. It uses Nodejs and global variables in the browser to distinguish the current environment, and then implements each of the underlying variables to expose a unified SET of apis for us to use. It also provides default values such as timeout, Headers, alidateStatus, etc., which are used when we do not pass override values.
6. [Axios/ Adapters/HTTP.js] Take a look at the implementation of Axios in Nodejs
// Adapters/HTTP... var http = require('http');
var https = require('https'); . module.exports =function httpAdapter(config) {
return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) {
...
var req = transport.request(options, functionhandleResponse(res) { ... }) // req error req.on('error'.functionhandleRequestError(err) { ... }); req.end(data); })}Copy the code
In Nodejs, the implementation of Axios is actually based on the HTTP or HTTPS module of Nodejs to initiate requests.
7. [Axios/ Adapters /xhr.js] Look at the implementation of Axios in the browser
// Adapters/HTTP,. var http =require('http');
var https = require('https'); . module.exports =function httpAdapter(config) {
return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) {... var req = transport.request(options,function handleResponse(res) {...// Process response and return
})
// Req error// Enter the./ Adapters/XHR file. module.exports =function xhrAdapter(config) {
return new Promise(function dispatchXhrRequest(resolve, reject) {... var request =newXMLHttpRequest(); . request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer),true); . request.onreadystatechange =function handleLoad() {... }; . request.onabort =function handleAbort() {...}
...
request.onerror = function handleError() {...}
...
request.ontimeout = function handleTimeout() {... }... request.send(requestData); . })} Handle req.on('error'.function handleRequestError(err) {... }); req.end(data); })}Copy the code
A complete Ajax library wrapper process, except that AXIOS exposes a Promise, so AXIOS works the same way on the browser side as it does on the Ajax side: it’s a wrapper through the browser’s XMLhttpRequest interface.
[Axios/lib/core/ axios.js] [Axios/lib/core/ axios.js] [Axios/lib/core/ axios.js] [Axios/lib/core/ axios.js]
/ / axios... var context = new Axios(defaultConfig); .function Axios(instanceConfig) {
this.defaults = instanceConfig;
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}Copy the code
The Axios constructor attaches the defaultConfig argument just passed to its this, and then adds an interceptors object with request and Response properties. Let’s take a look at the InterceptorManager constructor in both properties.
9, [Axios/lib/core/InterceptorManager js] in the constructor of the interceptor
/ / to enter the core/InterceptorManager. Js
InterceptorManager.prototype.use = function() {... } InterceptorManager.prototype.eject =function() {... } InterceptorManager.prototype.forEach =function forEach(fn) {... }Copy the code
Interceptors expose three methods: use, eject, and forEach. I’m sure many of you have used the use property when writing your interceptors. The last two are less commonly used, but you can see from their code that eject deletes the used content, and forEach loops through fn, and the whole interceptor part is read.
[Axios/lib/core/ axios.js] go back to the axios.js file and look at the Axios constructor.
. Axios.prototype.request =function request(config) {... }) Axios.prototype.getUri =function getUri(config) {...})
...
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
}));
};
});Copy the code
Next, under the Axios constructor, we mount nine methods to the prototype, including the following methods that we often use.
axios.request(config)
axios.getUri(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])Copy the code
After the constructor Axios, go back to our entry file Axios.
[Axios/lib/axios.js] return to the entry file
function createInstance(defaultConfig) {
var context = new Axios(defaultConfig);
var instance = bind(Axios.prototype.request, context);
utils.extend(instance, Axios.prototype, context);
utils.extend(instance, context);
return instance;
}Copy the code
Request and context. Axios.prototype.request is a function, context is a constructed object, This step above is why we can use static methods like axios.get.
[Axios/lib/helper/bind.js] see what the bind function does.
module.exports = function bind(fn, thisArg) {
return function wrap() {
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
return fn.apply(thisArg, args);
};
};Copy the code
Bind returns a new function, then makes a deep copy of the arguments, and then executes the second object argument passed in as the this parameter of a function using apply
Axios.prototype.request.bind(new Axios(defaultConfig);)Copy the code
[Axios/lib/axios.js] Then look at the remaining two lines in the entry file.
. utils.extend(instance, Axios.prototype, context); utils.extend(instance, context); .Copy the code
Instance is a function, Axios. Prototype and context are two objects.
[Axios/lib/utils.js] look at the implementation of utils.extend.
function extend(a, b, thisArg) {
forEach(b, function assignValue(val, key) {
if (thisArg && typeof val === 'function') {
a[key] = bind(val, thisArg);
} else{ a[key] = val; }});return a;
}Copy the code
Extend is simple enough to return the first parameter, inttance, and attach some static attributes to the function. If the value of the axios. prototype object is a function, the function is bound to this and mounted on instance. If it is not a function, it is mounted directly on the constructor.
Six. Summary and thinking
The entire Axios source code flow has been sorted out to see how it is implemented separately in HTTP and browser layers, how methods such as GET and POST are mounted, and how the most commonly used interceptors can not only be loaded by use, but can also be removed by eject. If you need to configure some parameters later and don’t know how to do it, or the documentation doesn’t satisfy you, look at the source code level.
Reference: http://www.axios-js.com/
The above content is their own summary, there will be mistakes or understanding bias, if there are questions, I hope you leave a message to correct, so as not to mistake people, if there are any questions please leave a message, we will try our best to answer it. Don’t forget to share it with your friends or give a “like” if it helps! You can also follow the author, view historical articles and follow the latest developments to help you become a full stack engineer!