Encapsulate the api request in the project with axios
- 2021-08-21 19:46:19
- OfStack
Pain points:
1. The backend has adjusted the url for all requests.
2. The backend requires adding 1 token to all request headers, or adding other global processing to the request.
3. The request code is written directly in each page, which seems bloated, concise and difficult to manage.
4. Seeing the request code, I don't understand what the request is for, and the semantics is not obvious enough. ...
The above list is a common problem, if there is no encapsulation of api, when more requests, modified to cry, to solve these problems can be carried out as follows
1. Encapsulate axios twice
2. Encapsulate all api requests as well
The following is the second encapsulation of axios with the file name network/index. js:
import axios from "axios";
import Cookies from "js-cookie";
// Set timeout time
const myAxios = axios.create({
timeout: 5000
});
// Jump login page
function nav2Login() {
location.href = '/xxxx/login'
}
// Add 1 Request interceptor
myAxios.interceptors.request.use(
function(config) {
// Do something before request is sent
config.headers["token"] = Cookies.get("token") || "";
return config;
},
function(error) {
// Do something with request error
return Promise.reject(error);
}
);
// Add 1 Response interceptor
myAxios.interceptors.response.use(
function(response) {
// Do something with response data
// This is just to 200 401 For example, Other status codes can be added as needed
if (response.status === 200) {
return response.data;
} else if (response.status === 401) {
nav2Login()
return Promise.reject();
} else {
return {
status: 0,
message: response.data.message
};
}
},
function(error) {
// Do something with response error
return Promise.reject(error);
}
);
export default myAxios;
The following is an encapsulation of the entire api, with the filename network/api. js:
import axios from "./index.js";
const API = {
userList: 'api/user/all', // User list
cityList: 'api/city/all', // City list
};
function Axios(obj) {
return axios({
...obj
}).catch(e => {
// Hold it here error, So that that follow-up code execution is not affect, and the appearance of a white screen is avoided
return {
status: 0,
message: " Network request exception "
};
});
}
// When naming a function, Try to be semantic
function getUserList(params) {
return Axios({
url: API.userList,
method: "post",
params
});
}
function getCityList(params) {
return Axios({
url: API.cityList,
method: "get",
params
});
}
export default {
getUserList,
getCityList,
}
You can mount these requests on a global variable, taking Vue as an example:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import api from "@/network/api.js";
Vue.prototype.$api = api;
new Vue({
router,
render: h => h(App)
}).$mount('#app')
The method used in the Vue project is as follows:
this.$api.getUserList(obj).then(res => {
// Deal with res
}).catch(err){
// Deal with err
}
// Or use async await
async getUserList () {
try {
const res = await this.$api.getUserList(obj)
// Deal with res
} catch (err) {
// Deal with err
}
}
Additional knowledge: Encapsulation of axios and api interface request in Vue project
Encapsulate axios:
/* Definition 1 A ajax Request function and its return value : promise Object ( The data returned asynchronously is : response.data) */
import axios from 'axios';
export default function ajax (url, data={}, type='GET') {
return new Promise(function (resolve, reject) {
// Execute asynchronous ajax Request
let promise
if (type === 'GET') {
// Prepare url query Parameter data ,
let dataStr = '' // Data splicing string
Object.keys(data).forEach(key => {
dataStr += key + '=' + data[key] + '&'
})
if (dataStr !== '') {
dataStr = dataStr.substring(0, dataStr.lastIndexOf('&'))
url = url + '?' + dataStr
}
// Send get Request
promise = axios.get(url)
} else {
// Send post Request
promise = axios.post(url, data)
}
promise.then(function (response) {
// Successful call resolve()
resolve(response.data)
}).catch(function (error) {
// Failed call reject()
reject(error)
})
})
}