In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what are the core knowledge points worth learning in Axios". In the operation of actual cases, many people will encounter such a dilemma. Next, let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
A brief introduction to Axios
Axios is a Promise-based HTTP client with the following features:
Support for Promise API
Ability to intercept requests and responses
Ability to convert request and response data
Client supports defense against CSRF attacks
Support for both browser and Node.js environments
Ability to cancel requests and automatically convert JSON data.
On the browser side, Axios supports most mainstream browsers, such as Chrome, Firefox, Safari, and IE 11. In addition, Axios has its own ecology:
After a brief introduction to Axios, let's analyze one of the core functions it provides-interceptors.
2. Design and implementation of HTTP interceptor.
2.1 brief introduction of interceptor
For most SPA applications, token is usually used for user authentication. This requires that after the authentication is passed, we need to carry the authentication information on each request. To meet this requirement, in order to avoid processing each request separately, we can add token information for each request by encapsulating a unified request function.
But at a later stage, if we need to set the caching time for some GET requests or control how often some requests are called, we need to constantly modify the request function to extend the corresponding functionality. At this point, if we are considering uniform processing of the response, our request function will become larger and harder to maintain. So how to solve this problem? Axios provides us with a solution-interceptor.
Axios is a Promise-based HTTP client, while the HTTP protocol is based on requests and responses:
So Axios provides a request interceptor and a response interceptor to handle the request and response respectively, and their functions are as follows:
Request interceptor: the function of this interceptor is to uniformly perform certain operations before the request is sent, such as adding a token field to the request header.
Response interceptor: the function of this kind of interceptor is to perform some operations uniformly after receiving the response from the server, such as automatically jumping to the login page when the response status code is 401.
It is easy to set the interceptor in Axios. Through the use method provided by the axios.interceptors.request and axios.interceptors.response objects, you can set the request interceptor and the response interceptor respectively:
/ / add request interceptor axios.interceptors.request.use (function (config) {config.headers.token = 'added by interceptor'; return config;}); / / add response interceptor axios.interceptors.response.use (function (data) {datadata.data = data.data +'-modified by interceptor'; return data;})
So how does the interceptor work? Before looking at the specific code, let's analyze its design ideas. The role of Axios is to send HTTP requests, while request interceptors and response interceptors are essentially functions that implement specific functions.
We can split sending HTTP requests into different types of subtasks according to the function, such as subtasks for processing request configuration objects, subtasks for sending HTTP requests, and subtasks for processing response objects. When we execute these subtasks in the specified order, we can complete a complete HTTP request.
After understanding this, we will analyze the implementation of Axios interceptor from three aspects: task registration, task scheduling and task scheduling.
2.2 Task Registration
Through the previous example of using the interceptor, we already know how to register the request interceptor and the response interceptor, where the request interceptor is used to handle the subtasks of the request configuration object, and the response interceptor is used to handle the subtasks of the response object. To figure out how tasks are registered, you need to understand the axios and axios.interceptors objects.
/ / lib/axios.js function createInstance (defaultConfig) {var context = new Axios (defaultConfig); var instance = bind (Axios.prototype.request, context); / / Copy axios.prototype to instance utils.extend (instance, Axios.prototype, context); / / Copy context to instance utils.extend (instance, context); return instance;} / / Create the default instance to be exported var axios = createInstance (defaults)
In the source code of Axios, we find the definition of the axios object, and it is clear that the default axios instance is created through the createInstance method, which ultimately returns the Axios.prototype.request function object. At the same time, we found the constructor of Axios:
/ / lib/core/Axios.js function Axios (instanceConfig) {this.defaults = instanceConfig; this.interceptors = {request: new InterceptorManager (), response: new InterceptorManager ()};}
In the constructor, we find the definition of the axios.interceptors object, and we know that the interceptors.request and interceptors.response objects are both instances of the InterceptorManager class. So next, take a closer look at the InterceptorManager constructor and the associated use methods to see how the task is registered:
/ / lib/core/InterceptorManager.js function InterceptorManager () {this.handlers = [];} InterceptorManager.prototype.use = function use (fulfilled, rejected) {this.handlers.push ({fulfilled: fulfilled, rejected: rejected}); / / returns the current index to remove the registered interceptor return this.handlers.length-1;}
By observing the use method, we can see that all registered interceptors are saved to the handlers property of the InterceptorManager object. Let's use a diagram to summarize the internal structure and relationship between Axios objects and InterceptorManager objects:
2.3 Task scheduling
Now we know how to register interceptor tasks, but just registering tasks is not enough. We also need to choreograph the registered tasks to ensure the order in which they are executed. Here we divide the completion of a complete HTTP request into three stages: processing the request configuration object, initiating the HTTP request and processing the response object.
Next, let's take a look at how Axios makes requests:
Axios ({url:'/ hello', method: 'get',}) .then (res = > {console.log (' axios res:', res) console.log ('axios res.data:', res.data)})
Through the previous analysis, we already know that the axios object corresponds to the Axios.prototype.request function object. The specific implementation of this function is as follows:
/ / lib/core/Axios.js Axios.prototype.request = function request (config) {config = mergeConfig (this.defaults, config); / / omit some codes var chain = [dispatchRequest, undefined]; var promise = Promise.resolve (config); / / Task scheduling this.interceptors.request.forEach (function unshiftRequestInterceptors (interceptor) {chain.unshift (interceptor.fulfilled, interceptor.rejected);}) This.interceptors.response.forEach (function pushResponseInterceptors (interceptor) {chain.push (interceptor.fulfilled, interceptor.rejected);}); / / Task scheduling while (chain.length) {promisepromise = promise.then (chain.shift (), chain.shift ());} return promise;}
The code for task orchestration is relatively simple, so let's take a look at the comparison between pre-and post-task choreography:
2.4 Task scheduling
After the task is choreographed, to initiate the HTTP request, we also need to schedule the task in the order in which it is scheduled. The specific scheduling method in Axios is very simple, as shown below:
/ / lib/core/Axios.js xios.prototype.request = function request (config) {/ / omit part of the code var promise = Promise.resolve (config); while (chain.length) {promisepromise = promise.then (chain.shift (), chain.shift ());}
Because chain is an array, we can constantly extract the set tasks through the while statement, and then assemble them into a Promise call chain to achieve task scheduling. The corresponding processing flow is shown in the following figure:
Let's review the complete process of using the Axios interceptor:
/ / add request interceptor-process request configuration object axios.interceptors.request.use (function (config) {config.headers.token = 'added by interceptor'; return config;}); / / add response interceptor-process response object axios.interceptors.response.use (function (data) {datadata.data = data.data +'-modified by interceptor'; return data;}) Axios ({url:'/ hello', method: 'get',}) .then (res = > {console.log (' axios res.data:', res.data)})
After introducing Axios's interceptor, let's summarize its advantages. By providing an interceptor mechanism, Axios makes it easy for developers to customize different processing logic during the life cycle of the request.
In addition, the capabilities of Axios can be flexibly extended through the interceptor mechanism, such as the axios-response-logger and axios-debug-log libraries enumerated in the Axios ecology.
Referring to the design model of the Axios interceptor, we can extract the following general task processing models:
Third, the design and implementation of HTTP adapter
3.1 default HTTP Adapter
Axios supports both browser and Node.js environment. For browser environment, we can send HTTP request through XMLHttpRequest or fetch API, while for Node.js environment, we can send HTTP request through Node.js built-in http or https module.
To support different environments, Axios introduces adapters. In the HTTP interceptor design section, we saw a dispatchRequest method that is used to send HTTP requests, and its implementation is as follows:
/ / lib/core/dispatchRequest.js module.exports = function dispatchRequest (config) {/ / omit partial code var adapter = config.adapter | | defaults.adapter; return adapter (config) .then (function onAdapterResolution (response) {/ / omit partial code return response;}, function onAdapterRejection (reason) {/ / omit partial code return Promise.reject (reason);});}
By looking at the dispatchRequest method above, we know that Axios supports custom adapters and also provides default adapters. For most scenarios, we do not need a custom adapter, but instead use the default adapter directly. Therefore, the default adapter contains the adaptation code for the browser and Node.js environment, and the specific adaptation logic is as follows:
/ / lib/defaults.js var defaults = {adapter: getDefaultAdapter (), xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName:' XmurXSRF color token, / /...} function getDefaultAdapter () {var adapter; if (typeof XMLHttpRequest! = = 'undefined') {/ / For browsers use XHR adapter adapter = require ('. / adapters/xhr') } else if (typeof process! = 'undefined' & & Object.prototype.toString.call (process) = =' [object process]') {/ / For node use HTTP adapter adapter = require ('. / adapters/http');} return adapter;}
In the getDefaultAdapter method, we first distinguish different platforms by specific objects in the platform, and then import different adapters. The specific code is relatively simple, which will not be introduced here.
3.2 Custom Adapter
In addition to the default adapter, we can also customize the adapter. So how do you customize the adapter? Here we can refer to the example provided by Axios:
Var settle = require ('. /.. / core/settle') Module.exports = function myAdapter (config) {/ / current timing: / /-the config configuration object has been merged with the default request configuration / /-the request converter has run / /-the request interceptor has run / / initiated the request using the provided config configuration object / / process the status of the Promise according to the response object return new Promise (function (resolve) Reject) {var response = {data: responseData, status: request.status, statusText: request.statusText, headers: responseHeaders, config: config, request: request} Settle (resolve, reject, response); / / after that: / /-the response converter will run / /-the response interceptor will run});}
In the above example, we focus on the basic requirements of the converter, the runtime point of the interceptor, and the adapter. For example, when the custom adapter is called, the Promise object needs to be returned. This is because the request scheduling is done through Promise chained calls within Axios, and unclear partners can reread the "Design and implementation of interceptor" section.
Now that we know how to customize the adapter, what's the use of customizing the adapter? In the Axios ecosystem, Po discovered the axios-mock-adapter library, which allows developers to easily simulate requests by customizing adapters. The corresponding usage examples are as follows:
Var axios = require ("axios"); var MockAdapter = require ("axios-mock-adapter"); / / set the mock adapter var mock = new MockAdapter (axios) on the default Axios instance; / / simulate the GET / users request mock.onGet ("/ users"). Reply (200,{ users: [{id: 1, name: "John Smith"}],}) Axios.get ("/ users") .then (function (response) {console.log (response.data);})
If you are interested in MockAdapter, you can learn about the axios-mock-adapter library for yourself. Now that we have introduced the interceptor and adapter of Axios, Po uses a diagram to summarize the request processing flow of Axios after using request interceptor and response interceptor:
IV. CSRF Defense
4.1 introduction to CSRF
Cross-site request forgery (Cross-site request forgery), usually abbreviated as "CSRF" or "XSRF", is an attack that hijacks users to perform unintended operations on currently logged-in Web applications.
The cross-site request attack, simply put, is that the attacker uses some technical means to deceive the user's browser to visit a website that he has authenticated and to run some operations (such as sending email, sending messages, and even property operations such as transferring money and buying goods). Because the browser has been authenticated, the website visited will be run as a real user action.
In order to better understand the above, Brother Po drew an example of a cross-site request attack:
In the figure above, the attacker exploits a loophole in user authentication in Web: "simple authentication can only guarantee that the request is sent from a user's browser, but not that the request itself is made voluntarily by the user." Since there are the above loopholes, how should we defend ourselves? Next, let's introduce some common CSRF defense measures.
4.2 CSRF Defense measures
4.2.1 check the Referer field
There is a Referer field in the HTTP header that indicates which address the request came from. When processing sensitive data requests, generally speaking, the Referer field should be under the same domain name as the requested address.
Take the mall operation in the example as an example, the Referer field address should usually be the web address where the mall is located, and it should also be under www.semlinker.com. If it is a request from a CSRF attack, the Referer field will be the address that contains the malicious URL and will not be under www.semlinker.com, so the server will be able to identify the malicious access.
This method is simple and easy, and only one step of verification is needed at the key access points. But this approach also has its limitations, because it relies entirely on the browser to send the correct Referer field. Although the content of this field is clearly defined in the HTTP protocol, it cannot guarantee the specific implementation of the visiting browser, nor can it guarantee that there are no security vulnerabilities in the browser that affect this field. It is also possible for an attacker to attack some browsers and tamper with their Referer fields.
4.2.2 synchronous form CSRF check
The CSRF attack is successful because the server cannot distinguish between normal requests and attack requests. To solve this problem, we can require all user requests to carry a token that CSRF attackers cannot get. For the form attack in the CSRF sample diagram, we can use the defense measure of "synchronous form CSRF check".
"synchronize the form CSRF check" is to render the token to the page when returning to the page, and to submit the CSRF token to the server by hiding the field or as a query parameter when the form form is submitted. For example, when rendering the page synchronously, add a query parameter of _ csrf to the form request so that the CSRF token will be submitted when the user submits the form:
User name: select avatar: submit
4.2.3 dual Cookie Defense
"dual Cookie defense" is to set the token in Cookie, submit the Cookie when submitting a request (POST, PUT, PATCH, DELETE), and bring the token that has been set in Cookie through the request header or request body. After receiving the request, the server makes a comparison and verification.
Let's take jQuery as an example to see how to set up CSRF token:
Let csrfToken = Cookies.get ('csrfToken'); function csrfSafeMethod (method) {/ / the following HTTP methods do not require CSRF protection return (/ ^ (GET | HEAD | OPTIONS | TRACE) $/ .test (method));} $ajaxSetup ({beforeSend: function (xhr, settings) {if (! csrfSafeMethod (settings.type) & &! this.crossDomain) {xhr.setRequestHeader (' xmurcsrf painting to kennel, csrfToken);},},})
After introducing the ways and defenses of CSRF attacks, let's take a look at how Axios protects against CSRF attacks.
4.3 Axios CSRF Defense
Axios provides two attributes, xsrfCookieName and xsrfHeaderName, to set the Cookie name of CSRF and the name of the HTTP request header, respectively. Their default values are as follows:
/ / lib/defaults.js var defaults = {adapter: getDefaultAdapter (), / / omit part of the code xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName:' XmurXSRFMurTOKENCE,}
We already know that Axios uses different adapters to send HTTP requests on different platforms. Let's take a browser platform as an example to see how Axios protects against CSRF attacks:
/ / lib/adapters/xhr.js module.exports = function xhrAdapter (config) {return new Promise (function dispatchXhrRequest (resolve, reject) {var requestHeaders = config.headers; var request = new XMLHttpRequest (); / / omit part of the code / / add xsrf header if (utils.isStandardBrowserEnv ()) {var xsrfValue = (config.withCredentials | | isURLSameOrigin (fullPath)) & & config.xsrfCookieName? Cookies.read (config.xsrfCookieName): undefined; if (xsrfValue) {requestHeaders [config.xsrfHeaderName] = xsrfValue;}} request.send (requestData);};}; "what are the core knowledge points worth learning in Axios"? thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
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.