Axios封装,响应拦截操作
0. 缘起
Axios封装是非常重要的一件事,我之前因为用的框架所以妹有怎么关心,既然要闪人,还是得自己思索怎么封装Axios的。
1. Axios的构成
2. Axios封装
2.1 全局头信息
axios.defaults.headers["Content-Type"] = "application/json;charset=UTF-8";
2.2 设置超时时间
axios.defaults.timeout = 1800000;
2.3 请求路由拦截
axios.interceptors.request.use(
function (config) {
if (sessionStorage.getItem("token")) {
config.headers["Authorization"] = sessionStorage.getItem("token");
}
return config;
},
function (error) {
return Promise.reject(error);
}
);
2.4 响应拦截
// 响应拦截
axios.interceptors.response.use(
function (response) {
const { data, message } = response
if (data.code !== 200) {
Message.error({
message: message,
duration: 1500,
showClose: true
});
}
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
function (err) {
const { status } = err.response ? err.response : { status: "" };
if (err && err.response) {
if (err?.response?.data?.message) {
err.message = err?.response?.data?.message
} else {
switch (status) {
case 400:
err.message = "请求错误(400)";
break;
case 401:
err.message = "未授权,请重新登录(401)";
resetRouter();
store.commit("SET_ROUTERS", []);
router.push("/login");
break;
case 403:
err.message = "拒绝访问(403)";
break;
case 404:
err.message = "请求出错(404)";
break;
case 405:
err.message = "请求未允许(405)";
break;
case 408:
err.message = "请求超时(408)";
break;
case 500:
err.message = "服务器错误(500)";
break;
case 501:
err.message = "服务未实现(501)";
break;
case 502:
err.message = "网络错误(502)";
break;
case 503:
err.message = "服务不可用(503)";
break;
case 504:
err.message = "网络超时(504)";
break;
case 505:
err.message = "HTTP版本不受支持(505)";
break;
default:
err.message = `连接出错(${err.response.status})!`;
}
}
} else {
err.message = "连接服务器失败!";
}
Message.error({
message: err.message,
duration: 1500,
showClose: true
});
return Promise.reject(err);
}
);
2.5 封装请求方法
// 封装请求方法
export function get(url, params, baseURL = "") {
let config = {};
config.params = params;
baseURL && (config.baseURL = baseURL);
return new Promise((resolve, reject) => {
axios
.get(url, config)
.then(res => {
resolve(res.data);
})
.catch(err => {
resolve({ success: false, message: err.message });
});
});
}
export function del(url, params, baseURL = "") {
let config = {};
config.data = params;
baseURL && (config.baseURL = baseURL);
return new Promise((resolve, reject) => {
axios
.delete(url, config)
.then(res => {
resolve(res.data);
})
.catch(err => {
resolve({ success: false, message: err.message });
});
});
}
export function post(url, params, query = {}, baseURL = "") {
let config = {};
config.params = query;
baseURL && (config.baseURL = baseURL);
return new Promise((resolve, reject) => {
axios
.post(url, typeof params === "object" ? JSON.stringify(params) : params, config)
.then(res => {
resolve(res.data);
})
.catch(err => {
resolve({ success: false, message: err.message });
});
});
}
export function put(url, params, query = {}, baseURL = "") {
let config = {};
config.params = query;
baseURL && (config.baseURL = baseURL);
return new Promise((resolve, reject) => {
axios
.put(url, typeof params === "object" ? JSON.stringify(params) : params, config)
.then(res => {
resolve(res.data);
})
.catch(err => {
resolve({ success: false, message: err.message });
});
});
}
2.6 使用该版本的请求
export function loginOut() {
return del( '/v1/auth/logout', {}, baseUrl)
}
3. 另一种封装Axios方法
import Vue from "vue";
import axios from "axios";
import {
contentType,
debounce,
invalidCode,
loginInterception
} from "@/config";
import store from "@/store";
import QS from "qs";
import router from "@/router";
import { Message } from "element-ui";
let loadingInstance;
const baseURL = process.env.VUE_APP_BASEURL;
/**
* @description 处理code异常
* @param {*} code
* @param {*} msg
*/
const handleCode = (code, msg) => {
switch (code) {
case invalidCode:
Message.warning(msg || `后端接口${code}异常`, "error");
store.dispatch("user/resetAccessToken").catch(() => {
});
if (loginInterception) {
location.reload();
}
break;
default:
Message.warning(msg || `后端接口${code}异常`, "error");
break;
}
};
const instance = axios.create({
baseURL,
timeout: 1800000,
headers: {
"Content-Type": contentType,
}
});
instance.interceptors.request.use(
(config) => {
let token = store.state.WWUser.token;
let hasToken = store.state.WWUser.token && store.state.WWUser.token.length
if (hasToken) {
config.headers['Authorization'] = token;
}
//这里会过滤所有为空、0、false的key,如果不需要请自行注释
// if (config.data)
// config.data = Vue.prototype.$baseLodash.pickBy(
// config.data,
// Vue.prototype.$baseLodash.identity
// );
if (
config.data &&
config.headers["Content-Type"] ===
"application/x-www-form-urlencoded;charset=UTF-8"
)
config.data = QS.stringify(config.data);
if (debounce.some((item) => config.url.includes(item)))
loadingInstance = Vue.prototype.$baseLoading();
return config;
},
(error) => {
return Promise.reject(error);
}
);
instance.interceptors.response.use(
(response) => {
if (loadingInstance) loadingInstance.close();
const { data, config } = response;
const { code, message } = data;
let successFlag = response.status;
// 是否操作正常
if (successFlag === 200) {
if (response.config.responseType === 'blob') {
return response
} else {
return data;
}
} else {
handleCode(code, message);
return Promise.reject(
"请求异常拦截:" +
JSON.stringify({ url: config.url, code, message }) || "Error"
);
}
},
(error) => {
if (loadingInstance) loadingInstance.close();
const { response, message } = error;
if (error.response && error.response.data) {
const { status, data } = response;
handleCode(status, data.message || message);
return Promise.reject(error);
} else {
let { message } = error;
if (message === "Network Error") {
message = "后端接口连接异常";
}
if (message.includes("timeout")) {
message = "后端接口请求超时";
}
if (message.includes("Request failed with status code")) {
const code = message.substr(message.length - 3);
message = "后端接口" + code + "异常";
}
Message.error(message || `后端接口未知异常`, "error");
return Promise.reject(error);
}
}
);
export default instance;
3.2 使用
// Get Department Name List
export function getDepNameList () {
return request({
url: '/working/findByDepartment',
method: 'post',
baseURL
})
}
人生到处知何似,应似飞鸿踏雪泥。