During the development of a VUE project, AXIOS is often used as an HTTP library in the project. Most of the company’s projects will choose to carry out secondary development on the JEECG-boot framework, which has a relatively mature axiOS application program. Based on my own experience in using AXIOS, I will make a summary of my experience in using AXIOS in VUE2.x version.
Axios encapsulates the essentials
The singleton pattern
The vast majority of requests in the project have the same common configuration of baseURL, response timeout, and so on, so you only need to create an instance once using axios.create, which also optimizes performance.
The interceptor
1. The intercept request
- Token parameter Carrying
- Get requests avoid caching
- Joins the request collection to handle multiple requests at the same time
- A form type request requires serialization of the parameters
2. Intercept the response
- Simplified response structure
- Unified error status code handling
Encapsulating tool function
-
Encapsulate get, POST, PUT,delete four public functions
-
Encapsulate common functions that support incoming requests for these four types
Code demo
The singleton pattern
Use axios.create to create an instance on which all subsequent operations will be performed.
// Create an instance
const service = axios.create({
// Public request headers
baseURL: apiBaseUrl,
// Request timeout
timeout: 9000
})
// Related interceptor processing
service...
// Export the instance
export {
service as axios
}
Copy the code
The interceptor
1. The intercept request
- Token parameter Carrying
Fetch the token from localStorage or sessionStorage and place it in headers on each request.
As to whether tokens are stored in LS or session, you can check my previous article.
If a request cannot carry a token in headers, you can use config.url to exclude the request.
service.interceptors.request.use(config= > {
const token = Vue.ls.get(ACCESS_TOKEN)
if (token) {
config.headers[ 'X-Access-Token' ] = token
}
return config
},(error) = > {
return Promise.reject(error)
})
Copy the code
- Get requests avoid caching
Browsers cache GET requests with the same URL link, which can result in some requests not getting the latest data. Add a timestamp to the GET request to solve this problem. The sample code here is time-stamped for all requests except dictionary requests, which can be modified based on project conditions.
service.interceptors.request.use(config= > {
if(config.method=='get') {if(config.url.indexOf("sys/dict/getDictItems") <0){
config.params = {
_t: Date.parse(new Date/ ())1000. config.params } } }return config
},(error) = > {
return Promise.reject(error)
})
Copy the code
-
The implementation code for canceling repeated requests is slightly more complex and is examined in detail at the end of this article
-
A form-type request that serializes the parameters
When the Axios instance sets the header’s content-type to ‘ ‘Application /x-www-form-urlencoded, the interceptor needs to serialize the parameter: config.params=qs.stringify(parmas). Because the project is full of JSON-formatted requests, I won’t cover the code here.
2. Intercept the response
- Simplified response structure
Axios wraps the value returned by the request in axiosResponse.data, and if it’s not processed in the interceptor, each request will need to extract the result and the code will be redundant.
service.interceptors.response.use((response) = > {
return response.data
}, (error) = > {
return Promise.reject(error)
})
Copy the code
- Unified error status code handling
Generally speaking, the format of the request returned from the background is specified, and different response status codes represent different meanings. For example, 401 indicates unauthorized resources, 404 indicates non-existent resources, and 500 indicates processing errors. We can then handle these error cases uniformly in interceptors.
const errHandler = (error) = > {
if (error.response) {
switch (error.response.status) {
case 401:
notification.error({
message: 'System info'.description: 'Not authorized, please log in again'.duration: 4
})
break
case 404:...break
case 500:...break
default:
notification.error({
message: 'System info'.description: data.message,
duration: 4
})
break}}return Promise.reject(error)
};
service.interceptors.response.use((response) = > {
return response.data
}, errHandler)
Copy the code
Encapsulating tool function
-
Encapsulate get, POST, PUT,delete four public functions
Encapsulate them into utility functions for easy call. Take encapsulating GET requests as an example. Note that the return value of the getAction function is of type AxiosPromise.
import { axios } from '@/utils/request' export function getAction(url,parameter) { return axios({ url: url, method: 'get'.params: parameter }) } // Example getAction('sys/dict/getDictItems').then(res= > { console.log(res) }) Copy the code
-
Encapsulate common functions that support incoming requests for these four types
In the form submission, if the ID is present, it indicates modification, and if the ID is not new, this is similar to the saveOrUpdate method provided by Mybatis. So it also encapsulates a function that supports all four requests. The important thing to note here is that the parameter names are different depending on how AXIos requests. Params is used for GET and DELETE, and Data is used for POST and PUT.
export function httpAction(url,parameter,method) {
// Select params or data
let paramOrData=['GET'.'DELETE'].some(item= >item===method.toUpperCase())?'params':'data'
return axios({
url: url,
method:method,
[paramOrData]: parameter
})
}
// Example
let url = this.url.add, method = 'post'
if (this.model.id) {
url = this.url.edit
method = 'put'
}
httpAction(url, formData, method).then((res) = > {
console.log(res)
})
Copy the code
How do I avoid repeated requests for simultaneous segments
When the same request is triggered multiple times, multiple responses are received, which can lead to problems such as multiple page redraws. So how does the front end solve this problem?
Start by defining a Map collection of cancelers provided by Axios
Canceler is used to cancel an existing request in a request interception, and the current request is loaded into the Map.
Move data out of the Map collection in response interception.
This ensures that if multiple requests are made at the same time, only one response will be processed, but it does not relieve the pressure on the server. Multiple requests will still be processed by the server, but the front-end will only process the response once.
The program was learned on Baidu
The implementation code is as follows:
- Define the Canceler utility class
let pendingMap = new Map(a);const getPendingUrl = (config) = > [config.method, config.url].join('&');
export const removePending=(config) = > {
const url = getPendingUrl(config);
if (pendingMap.has(url)) {
constcancel = pendingMap.get(url); cancel && cancel(url); pendingMap.delete(url); }}export const addPending=(config) = > {
removePending(config);
const url = getPendingUrl(config);
config.cancelToken =new axios.CancelToken((cancel) = > {
if (!pendingMap.has(url)) {
pendingMap.set(url, cancel);
}
});
}
Copy the code
Used in the Axios interceptor
service.interceptors.request.use(config= >{... addPending(config)return config
},(error) = > {
return Promise.reject(error)
})
service.interceptors.response.use((response) = >{... removePending(response.config)return response.data
}, (error) = > {
return Promise.reject(error)
})
Copy the code
If some requests do not need to be handled this way, they can be excluded by the URL.
This is probably what Axios is all about in the project, if there are any missing points please point out in the comments section. Finally, I wish you a healthy Dragon Boat Festival, dumplings are very fragrant.