// 封装HTTP请求
import axios from 'axios'
import router from '@/router/routers'
import { getToken } from '@/utils/auth'
import store from "@/store";
import { ElMessage } from 'element-plus'
import qs from 'qs'
// import { hasArray } from "./util"
// 创建axios实例
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 1200000 // 请求超时时间
})
// request拦截器
service.interceptors.request.use(
(config) => {
let token = getToken();
if (token) {
// 让每个请求携带自定义token 请根据实际情况自行修改
config.headers['Authorization'] = token;
}
// isFormData 为自定义字段,标识是否以Form表单数据形式进行传递
config.headers['Content-Type'] = config.isFormData ? 'multipart/form-data' : 'application/json';
//针对get方式传递数组进行序列化
if (config.method.toLowerCase() === 'get' && hasArray(config.params)) {
config.paramsSerializer = {
serialize: function(params) {
return qs.stringify(params, { arrayFormat: 'repeat'});
}
};
}
return config;
},
(error) => {
Promise.reject(error);
}
)
// response 拦截器
service.interceptors.response.use(
(response) => {
const code = response.data.code;
if (code !== 200) {
ElMessage.error(response.data.message || response.data.msg);
return Promise.reject('error');
} else {
// 文件流,处理文件名,"content-disposition"头部字段需要后端配合添加。
if(response.config.responseType == 'blob' && response.headers["content-disposition"]) {
const temp =response.headers["content-disposition"].split(";")[1].split("filename=")[1];
const fileName = decodeURIComponent(temp);
return {
fileName,
file: response.data
}
}
// 正常数据
return response.data;
}
},
(error) => {
let code = 0;
try {
code = error.response.data.status;
} catch (e) {
if (error.toString().indexOf('Error: timeout') !== -1) {
ElMessage.error('网络请求超时');
return Promise.reject(error);
}
}
if (code) {
if (code === 401) {
// 退出登录,用户登录界面提示
store.dispatch('user/Logout').then(() => {
window.location.reload();
})
} else if (code === 403) {
router.push({ path: '/403' })
} else {
const errorMsg = error.response.data.message;
if (errorMsg !== undefined) {
ElMessage.error(errorMsg);
}
}
} else {
ElMessage.error('接口请求失败');
}
return Promise.reject(error);
}
)
// 校验对象属性中是否含有数组
function hasArray(obj) {
if(!obj) return false;
for (let key in obj) {
if (Array.isArray(obj[key])) {
return true;
}
}
return false;
}
export default service;
小提一嘴,关于get方式传递数组进行序列化,网上绝大多数都是以函数的方式传递,但是axios中只有axios@1.3.5版本及以上才进行修改,支持函数形式(我的是1.3.4),所以低版本需要注意。
接口封装:
import request from '@/utils/request.js'
// post
export function postApi(data) {
return request({
url: '...',
method: 'post',
data,
isFormData: true // 表单数据类型(可选)
})
}
// get
export function getApi(params) {
return request({
url: '...',
method: 'get',
params
})
}
// delete
export function deleteApi(data) {
return request({
url: '...',
method: 'delete',
data
})
}
// put
export function putApi(data) {
return request({
url: '...',
method: 'put',
data
})
}