I often come across AXIOS when LEARNING and doing projects. The previous projects are usually configured with AXIOS, so I always have a general impression. Recently, I had an opportunity to manually configure AXIOS
Benefits of AXIos encapsulation
The benefits of AXIos packaging are unified processing, improved efficiency, and ease of maintenance.
You can use the AXIos request interface as follows
axios.get('http://localhost:10086/user? ID=12345')
.then(response= > {
// Successful operation...
})
.catch(error= > {
// Operation after failure...
});
Copy the code
However, when there are more interface requests and requirements, such code should be written in every place where interface requests are needed in the project, which will produce a lot of repetitive code, reducing our development efficiency and increasing maintenance costs.
Packaging ideas
We need to configure AXIOS centrally at once to fit most scenarios for our project. We can create a new JS file, create an axios instance with custom configuration, and then configure the instance, add some processing we need before the request (request body processing), after the request (return result processing), and export it for use.
Configuration priority
Configurations are merged in a priority order. The order is: the library defaults found in lib/defaults.js, then the instance defaults property, and finally the requested Config parameters. (We can also deal with some special scenes separately.)
Lib /defaults.js in the axiOS library file under node_modules.
Custom instance defaults
const instance = axios.create({
baseURL: 'https://api.example.com'
});
Copy the code
The requested config parameter
axios({
method:'get'.url:'http://bit.ly/2mTM3nY'.responseType:'stream' }).then(function(response) { response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))});Copy the code
Axios instance configuration
1. Define some general configurations
- Set the BaseUrl
BaseUrl can be stored in production, development, test, etc. We can create a config.js file to store baseUrl. If it is vue or React, we can create a env file to store baseUrl.
- Timeout Specifies the timeout period for a request
- Content-type (Application/X-www-form-urlencoded, multipart/form-data, Application /json…); , etc.
import axios from 'axios'
export const request = createAxiosInstance()
function createAxiosInstance () {
const instance = axios.create({
baseURL: process.env.REACT_APP_BASE_URL,
timeout: 5000.headers: {
// A unified request header can be defined
post: {
'Content-Type': 'application/json'}... }})return instance
}
Copy the code
2. Add some actions we need before the request.
- For example, you need to add a token to the request header
- Request parameter nulled processing
(In the example below, empty name and personId are passed, which can cause confusion. Some back-end processes do this, but the front end avoids this.)
- Loading animation is enabled every time the interface requests it
// Add request interceptor (something to do before sending the request)
instance.interceptors.request.use((config) = > {
// Add a function to enable the loading effect
loading.open()
// If the token exists, it is added to the request header
token && (config.headers.Authorization = token)
// Filter null undefined '' in request parameters
cleanObject()
return config
})
Copy the code
After the request is returned, add the interception operation.
- Process successfully returned data
For example, the data returned by the backend may have many nested layers, so you can return the data you need directly, so that the business code can get the final data directly, without having to deconstruct it every time, etc.
- An exception is reported after the unified processing fails
Interface requests can fail as well as succeed. If you don’t want to have to write failed logic code every time you write an interface request, which is almost always repeated, you can focus on unified exception handling of the interface here. For example, judge the status code or backend custom code, and display the error message returned by the backend.
// Add a response interceptor (do something with the response data)
instance.interceptors.response.use((response) = > {
// You can add a function to disable the loading effect
loading.close()
// Deconstruct the data that returns the result
const res = response.data
// Judge the custom code and return the successful data
const validateStatus = /^(2|3)\d{2}$/ //code starting with 2 or 3 is considered successful
if (validateStatus.test(res.code)) {
return res // Return the data we need
}
// Determine the failed code and perform operations such as prompting
if (res.code === 401) {
message.error(res.msg)
} else {
message.warning(res.msg)
}
return Promise.reject(res)
},
(error) = > {
loading.close()
if (error.response.status === 401) {
message.error('Token invalid, please log in again! ')
removeStorageToken()
setTimeout(() = > {
window.location.href = '/login'
}, 2000)}else {
if (!window.navigator.onLine) {
message.warning('Network is abnormal. Please check whether the network is properly connected.')}else if (error.code === 'ECONNABORTED') {
message.warning('Request timed out')}else {
message.warning('Server exception, please contact administrator')}}return Promise.reject(error) // Continue the error to the specific page})Copy the code
There are some error handling based on THE HTTP status code and custom code. After error interception, the page does not need to be handled every time when the business interface is called. Of course, it needs to be configured according to different project requirements.
Unified management of request interface methods
In general, we will write all the interface request methods together for unified management, and it is convenient to find and maintain when changing later.We can create a new folder to manage API requests (such as apiList) and put our various request files (grouped here by function) in it. For example, user.js stores user-related requests, and so on. The page can then make interface calls directly referencing methods.
import { request } from '.. /axios'
// Get user information
export function getUserInfo (userId) {
return request.get(`/sys/user/info/${userId}`)}Copy the code
Just call the method directly on the component or page
Let’s finish with a full example! You can refer to ~
This example configuration applies to vUE or React. Of course, the configuration of each project is different. You need to modify and expand the configuration according to your own project
import axios from 'axios'
export const request = createAxiosInstance()
function createAxiosInstance () {
const instance = axios.create({
baseURL: process.env.REACT_APP_BASE_URL,
timeout: 5000.headers: {
// A unified request header can be defined
post: {
'Content-Type': 'application/json'}... }})// Add request interceptor (something to do before sending the request)
instance.interceptors.request.use((config) = > {
// Add a function to enable the loading effect
loading.open()
// If the token exists, it is added to the request header
token && (config.headers.Authorization = token)
// Filter null undefined '' in request parameters
cleanObject()
return config
})
// Add a response interceptor (do something with the response data)
instance.interceptors.response.use((response) = > {
// You can add a function to disable the loading effect
loading.close()
// Deconstruct the data that returns the result
const res = response.data
// Judge the custom code and return the successful data
const validateStatus = /^(2|3)\d{2}$/ //code starting with 2 or 3 is considered successful
if (validateStatus.test(res.code)) {
return res
}
// Determine the failed code and perform operations such as prompting
if (res.code === 401) {
message.error(res.msg)
} else {
message.warning(res.msg)
}
return Promise.reject(res)
},
(error) = > {
loading.close() // You can add a function to disable the loading effect
if (error.response.status === 401) {
message.error('Token invalid, please log in again! ')
removeStorageToken()
setTimeout(() = > {
window.location.href = '/login'
}, 2000)}else {
if (!window.navigator.onLine) {
message.warning('Network is abnormal. Please check whether the network is properly connected.')}else if (error.code === 'ECONNABORTED') {
message.warning('Request timed out')}else {
message.warning('Server exception, please contact administrator')}}return Promise.reject(error) // Continue the error to the specific page})return instance
}
Copy the code