In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "what is the core principle of Axios". In daily operation, I believe many people have doubts about what the core principle of Axios is. The editor consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful for you to answer the doubt of "what is the core principle of Axios?" Next, please follow the editor to study!
A brief introduction to axios
What is axios?
Axios is a promise-based HTTP library that can be used in browsers and node.js.
What are the features of axios? (I have to say how many times the interview was asked.)
Create a XMLHttpRequests from a browser from a node.js
Create a http request
Support for Promise API
Intercept request and response conversion request and response data
Cancel the request
Automatic conversion of JSON data
Client supports defense against XSRF
In fact, axios can be used in browsers and node.js because it automatically determines what the current environment is, and if it is a browser, it implements axios based on XMLHttpRequests. If it is a node.js environment, it will implement axios based on node's built-in core module http. To put it simply, the basic principle of axios is
Axios still belongs to XMLHttpRequest, so you need to implement an ajax. Or based on http.
You also need a promise object to process the results.
II. Basic mode of use
The basic ways of using axios are
Axios (config)
Axios.method (url, data, config)
/ / index.html file point I send the request document.querySelector ('.btn'). Onclick = function () {/ / respectively use the following method calls to check the effect of myaxios axios.post ('/ postAxios', {name: 'Xiaomei post'}). Then (res = > {console.log (' postAxios successful response', res) }) axios ({method: 'post', url:' / getAxios'}) .then (res = > {console.log ('getAxios successful response', res);})}
Third, realize axios and axios.method
From the use of axios (config), you can see that the exported axios is a method. From the use of axios.method (url, data, config), we can see that there are methods such as get,post on the exported axios or on the prototype.
The exported axios is actually a method in an Axios class.
Such as the code, so the core code is request. When we export request, we can call axios in the form of axios (config).
Class Axios {constructor () {} request (config) {return new Promise (resolve = > {const {url ='', method = 'get', data = {}} = config; / / send ajax request const xhr = new XMLHttpRequest (); xhr.open (method, url, true) Xhr.onload = function () {console.log (xhr.responseText) resolve (xhr.responseText);} xhr.send (data);})}}
How to derive it? It's very simple, new Axios, get the axios instance, and then get the request method on the instance.
/ / the final method to export axios, that is, the request method of the instance function CreateAxiosFn () {let axios = new Axios (); let req = axios.request.bind (axios); return req;} / / gets the final global variable axios let axios = CreateAxiosFn ()
Click to view the myAxios.js at this time
Now axios is actually the request method.
You may be confused, because I was also confused when I looked at the source code: why not just write a request method and export it? You have to make such a big detour. No rush. I'll talk about it later.
Now that a simple axios is complete, let's introduce the myAxios.js file and test if it can be used.
Simply set up the server:
/ / server.js var express = require ('express'); var app = express (); / / set to allow cross-domain access to the service. App.all ('*', function (req, res, next) {res.header ('Access-Control-Allow-Origin',' *); res.header ('Access-Control-Allow-Headers',' Content-Type'); res.header ('Access-Control-Allow-Methods',' *'); res.header ('Content-Type',' application/json;charset=utf-8'); next ();}) App.get ('/ getTest', function (request, response) {data = {'FrontEnd':' front end', 'Sunny':' Sunshine'}; response.json (data);}); var server = app.listen (5000, function () {console.log ("server startup");}) / / index.html I send the request document.querySelector ('.btn'). Onclick = function () {/ / use the following method calls to check the effect of myaxios axios ({method: 'get', url:' http://localhost:5000/getTest'}). Then (res = > {console.log ('getAxios successful response', res) })}
Click the button to see if you can successfully get the data.
It was found to be a success.
You are to be congratulated
Now let's implement the form of axios.method ().
Idea: we can add these methods to Axios.prototype. The request method is called internally by these methods, as shown in the code:
/ / define get,post... Method, const methodsArr = ['get',' delete', 'head',' options', 'put',' patch', 'post']; methodsArr.forEach (met = > {Axios.prototype [met] = function () {console.log (' execute'+ met+' method') / / processing a single method if (['get',' delete', 'head',' options'] .parameters (met)) {/ / 2 parameters (url [, config]) return this.request ({method: met, url: arguments [0]) ... arguments [1] | | {}})} else {/ / 3 parameters (url [, data [, config]]) return this.request ({method: met, url: arguments [0], data: arguments [1] | {} ... arguments [2] | | {}})})
We iterate through the methodsArr array and add the corresponding methods to Axios.prototype in turn. Note that these methods accept only two parameters, such as' get', 'delete',' head', 'options'. And the other three parameters are acceptable, as you know, get does not put the parameters in body.
However, have you found that we are just adding the corresponding method to the prototype of Axios, and we are exporting the request method, so what should we do? Simply transfer the methods from Axios.prototype to request.
Let's first implement a tool method that mixes b's method with a
Const utils = {extend (typeof b, context) {for (let key in b) {if (b.hasOwnProperty (key)) {if (typeof b [key] = = 'function') {a [key] = b [key] .bind (context);} else {a [key] = b [key]}
Then we can use this method to transport the methods on Axios.prototype to request.
Let's just modify the previous CreateAxiosFn method.
Function CreateAxiosFn () {let axios = new Axios (); let req = axios.request.bind (axios); add code utils.extend (req, Axios.prototype, axios) return req;}
Click to view the myAxios.js at this time
Now test whether you can call axios in the form of axios.get ().
Click me to send the request document.querySelector ('.btn'). Onclick = function () {axios.get ('http://localhost:5000/getTest'). Then (res = > {console.log (' getAxios successful response', res);})}
It was an expected success again. Before completing the next function, give the complete code of the current myAxios.js
Class Axios {constructor () {} request (config) {return new Promise (resolve = > {const {url ='', method = 'get', data = {} = config; / / send ajax request console.log (config); const xhr = new XMLHttpRequest (); xhr.open (method, url, true) Xhr.onload = function () {console.log (xhr.responseText) resolve (xhr.responseText);} xhr.send (data);})}} / / define get,post... Method, const methodsArr = ['get',' delete', 'head',' options', 'put',' patch', 'post']; methodsArr.forEach (met = > {Axios.prototype [met] = function () {console.log (' execute'+ met+' method') / / processing a single method if (['get',' delete', 'head',' options'] .parameters (met)) {/ / 2 parameters (url [, config]) return this.request ({method: met, url: arguments [0]) ... arguments [1] | | {}})} else {/ / 3 parameters (url [, data [, config]]) return this.request ({method: met, url: arguments [0], data: arguments [1] | {} ... arguments [2] | | {}})}) / / tool method Methods or properties that implement b are mixed with a / / the method should also be mixed with const utils = {extend (afort b, context) {for (let key in b) {if (b.hasOwnProperty (key)) {if (typeof b [key] = 'function') {a [key] = b [key] .bind (context) } else {a [key] = b [key]}} / / final method to export axios-"that is, the instance's request method function CreateAxiosFn () {let axios = new Axios (); let req = axios.request.bind (axios); / / mixing method to handle axios's request method so that it has get,post... The method utils.extend (req, Axios.prototype, axios) return req;} / / gets the final global variable axios let axios = CreateAxiosFn ()
IV. Request and response interceptor
Let's take a look at the use of interceptors.
/ / add request interceptor axios.interceptors.request.use (function (config) {/ / do something before sending request return config;}, function (error) {/ / do something to request error return Promise.reject (error);}); / / add response interceptor axios.interceptors.response.use (function (response) {/ / do something to response data return response }, function (error) {/ / do something to respond to errors return Promise.reject (error);})
What does interceptor mean? In fact, when we send a request, we will first execute the code of the request interceptor, and then actually execute the request, which will do something to the config, that is, the parameters we passed when we sent the request.
When receiving the response, the code of the response interceptor will be executed first, and then the response data will be returned, which will perform a series of operations on the response, that is, the response data.
How can it be realized? It needs to be clear that the interceptor is also a class that manages responses and requests. So let's implement the interceptor first.
Class InterceptorsManage {constructor () {this.handlers = [];} use (fullfield, rejected) {this.handlers.push ({fullfield, rejected})}}
We use the statements axios.interceptors.response.use and axios.interceptors.request.use to trigger the interceptor to execute the use method.
Indicates that there is a response interceptor and a request interceptor on the axios. So how to achieve Axios? Look at the code.
Class Axios {constructor () {new code this.interceptors = {request: new InterceptorsManage, response: new InterceptorsManage}} request (config) {return new Promise (resolve = > {const {url ='', method = 'get', data = {}} = config / / send ajax request console.log (config); const xhr = new XMLHttpRequest (); xhr.open (method, url, true); xhr.onload = function () {console.log (xhr.responseText) resolve (xhr.responseText);}; xhr.send (data) })}}
As you can see, there is an object interceptors on the axios instance. This object has two interceptors, one for processing requests and one for handling responses.
So, when we execute the statements axios.interceptors.response.use and axios.interceptors.request.use, we implement to get the interceptors object on the axios instance, then get the response or request interceptor, and then execute the use method of the corresponding interceptor.
When the use method is executed, the callback function we passed in push is added to the interceptor's handlers array.
Have you found a problem here? This interceptors object is on Axios, and what we are exporting is the request method. What a familiar question, it was mentioned above). In the same way as above, the method is to move the methods and properties on Axios to request, that is, to traverse the method on the Axios instance, so that the interceptors object can be mounted on the request.
So just change the CreateAxiosFn method.
Function CreateAxiosFn () {let axios = new Axios (); let req = axios.request.bind (axios); / / blending method to handle the request method of axios so that it has get,post... Method utils.extend (req, Axios.prototype, axios) add code utils.extend (req, axios) return req;}
Well, now that request also has an interceptors object, when to take the callback function previously saved by handler in the interceptors object.
Yes, when we send a request, we first get the handlers of the request interceptor to execute it. Then execute the request we sent, and then get the handlers of the response interceptor to execute.
Therefore, this is what happened before we were going to modify the request method we wrote earlier.
Request (config) {return new Promise (resolve = > {const {url ='', method = 'get', data = {} = config; / / send ajax request console.log (config); const xhr = new XMLHttpRequest (); xhr.open (method, url, true); xhr.onload = function () {console.log (xhr.responseText) resolve (xhr.responseText) }; xhr.send (data);})}
But now in request you have to execute not only the send ajax request, but also the callback function in the interceptor handlers. So, the best thing to do is to encapsulate the request to execute ajax into a method
Request (config) {this.sendAjax (config)} sendAjax (config) {return new Promise (resolve = > {const {url ='', method = 'get', data = {} = config; / / send ajax request console.log (config); const xhr = new XMLHttpRequest (); xhr.open (method, url, true) Xhr.onload = function () {console.log (xhr.responseText) resolve (xhr.responseText);}; xhr.send (data);})}
All right, now we need to get the callback in handlers
Request (config) {/ / interceptor and request assembly queue let chain = [this.sendAjax.bind (this), undefined] / / paired The failed callback temporarily does not handle / / request interception this.interceptors.request.handlers.forEach (interceptor = > {chain.unshift (interceptor.fullfield, interceptor.rejected)}) / / response intercept this.interceptors.response.handlers.forEach (interceptor = > {chain.push (interceptor.fullfield, interceptor.rejected)}) / / execution queue, one pair at a time And assign the latest value let promise = Promise.resolve (config) to promise While (chain.length > 0) {promise = promise.then (chain.shift (), chain.shift ())} return promise;}
We first put the sendAjax request and undefined into the chain array, and then put the paired callback of the request interceptor's handlers into the chain array header. Then reverse the acceptance callback of the handlers that responds to the interceptor to the tail of the chain array.
Then gradually take the paired callback of the chain array to execute.
Promise = promise.then (chain.shift (), chain.shift ())
This sentence is actually constantly passing the config from the previous promise to the next promise, during which the config may be called back to make some changes. What does it mean? Let's explain it with an example.
First of all, the interceptor is used like this.
/ / add request interceptor axios.interceptors.request.use (function (config) {/ / do something before sending request return config;}, function (error) {/ / do something to request error return Promise.reject (error);}); / / add response interceptor axios.interceptors.response.use (function (response) {/ / do something to response data return response }, function (error) {/ / do something to respond to errors return Promise.reject (error);})
And then when you execute request. The data of the chain array looks like this
Chain = [function (config) {/ / do something before sending request return config;}, function (error) {/ / do something to request error return Promise.reject (error);} this.sendAjax.bind (this), undefined, function (response) {/ / do something return response to response data }, function (error) {/ / do something to respond to errors return Promise.reject (error);}]
First
Execute the first promise.then (chain.shift (), chain.shift ()), that is
Promise.then (function (config) {/ / do something before sending the request return config;}, function (error) {/ / do something wrong to the request return Promise.reject (error);})
In general, promise is in resolved status and executes a successful callback, that is, execution
Function (config) {/ / what do you do before sending the request return config;}
Promise.then is going to return a new promise object. To distinguish, here, I will call this new promise object the first new promise object, and the first new promise object will call the
Function (config) {/ / what do you do before sending the request return config;}
The result of the execution is passed into the resolve function
Resolve (config)
Make the state of the first new promise object returned is resovled, and the data of the first new promise object is config.
Here you need to have a good understanding of the principles of Promise. So in my previous article, I wrote about the core principle of handwritten Promise. I am no longer afraid that the interviewer will ask me the Promise principle. You can take a look at it.
Next, execute
Promise.then (sendAjax (config), undefined)
Note: promise here is the first new promise object mentioned above.
The execution of promise.then returns the second new promise object.
Because the state of the promise in promise.then, the first new promise object, is resolved, sendAjax () is executed. And the data of the first new promise object is fetched into sendAjax () as a config.
When the sendAjax is finished, a response is returned. This response is saved in the data of the second new promise object.
Next, execute
Promise.then (function (response) {/ / do something to response data return response;}, function (error) {/ / do something to response error return Promise.reject (error);})
Similarly, the data of the second new promise object is taken out and passed in as a response parameter
Function (response) {/ / do something to the response data return response;}
After the meal, a promise object is returned, and the data of this promise object holds the result of the execution of this function, that is, the return value response.
And then through return promise
This promise is returned. Huh? How to remove promise's data. Let's take a look at how we get the response data.
Axios.get ('http://localhost:5000/getTest'). Then (res = > {console.log (' getAxios successful response', res);})
Receive response data in then. So the principle is the same as above, taking the data of the returned promise as the res parameter.
Now take a look at our complete myAxios code to get a comprehensive understanding.
Class InterceptorsManage {constructor () {this.handlers = [] } use (fullfield, rejected) {this.handlers.push ({fullfield, rejected})}} class Axios {constructor () {this.interceptors = {request: new InterceptorsManage Response: new InterceptorsManage}} request (config) {/ / interceptor and request assembly queue let chain = [this.sendAjax.bind (this), undefined] / / paired Failed callback temporarily does not handle / / request intercept this.interceptors.request.handlers.forEach (interceptor = > {chain.unshift (interceptor.fullfield, interceptor.rejected)}) / / response intercept this.interceptors.response.handlers.forEach (interceptor = > {chain.push (interceptor.fullfield, interceptor.rejected)}) / / execute queue Execute one pair at a time and give promise the latest value let promise = Promise.resolve (config) While (chain.length > 0) {promise = promise.then (chain.shift (), chain.shift ())} return promise;} sendAjax () {return new Promise (resolve = > {const {url ='', method = 'get', data = {}} = config; / / send ajax request console.log (config) Const xhr = new XMLHttpRequest (); xhr.open (method, url, true); xhr.onload = function () {console.log (xhr.responseText) resolve (xhr.responseText);}; xhr.send (data);})} / / define get,post... Method, const methodsArr = ['get',' delete', 'head',' options', 'put',' patch', 'post']; methodsArr.forEach (met = > {Axios.prototype [met] = function () {console.log (' execute'+ met+' method') / / processing a single method if (['get',' delete', 'head',' options'] .parameters (met)) {/ / 2 parameters (url [, config]) return this.request ({method: met, url: arguments [0]) ... arguments [1] | | {}})} else {/ / 3 parameters (url [, data [, config]]) return this.request ({method: met, url: arguments [0], data: arguments [1] | {} ... arguments [2] | | {}})}) / / tool method The method of implementing b is mixed with a / / the method should also be mixed with const utils = {extend (afort b, context) {for (let key in b) {if (b.hasOwnProperty (key)) {if (typeof b [key] = 'function') {a [key] = b [key] .bind (context) } else {a [key] = b [key]} / / final method to export axios-"that is, the request method function CreateAxiosFn () {let axios = new Axios (); let req = axios.request.bind (axios) of the instance / / mix the method to handle the request method of axios to make it have get,post... The method utils.extend (req, Axios.prototype, axios) return req;} / / gets the final global variable axios let axios = CreateAxiosFn ()
To test whether the interceptor is functioning properly.
Click I send request / / add request interceptor axios.interceptors.request.use (function (config) {/ / do something before sending request config.method = "get"; console.log ("intercepted by my request interceptor, :", config); return config }, function (error) {/ / do something to the request error return Promise.reject (error);}); / / add the response interceptor axios.interceptors.response.use (function (response) {/ / do something to the response data console.log ("blocked by my response, ") Response = {message: "response data has been replaced by me, aha"} return response;}, function (error) {/ / do something console.log ("wrong"); return Promise.reject (error);}) Document.querySelector ('.btn'). Onclick = function () {/ / use the following method calls to see the effect of myaxios axios ({url: 'http://localhost:5000/getTest'}). Then (res = > {console.log (' response', res);})}
Intercept succeeded!
At this point, the study of "what is the core principle of Axios" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.