继续搭建
axios的使用
下载axios的两个包 axios 和 @types/axios
npm i axios -S npm i @types/axios -D
然后在项目的根目录中创建utils的文件夹,在这个文件夹中创建我们的请求文件request.ts
封装axios
在request文件中导入axios并且创建axios的实例
import axios, { AxiosRequestConfig } from 'axios';
// 创建一个axios的实例
// VITE_API_URL是我们的请求路径,在.env类型文件中创建
const service = axios.create({
baseURL: import.meta.env.VITE_API_URL as any,
timeout: 5000,
headers: { 'Content-Type': 'application/json' },
});
配置axios的拦截器
请求拦截器,在这个拦截器中可以进行一些操作,比如添加一些请求头,添加鉴权token还有设置loading效果等
// 请求拦截器
service.interceptors.request.use(
(config: myConfig) => {
// 过滤掉请求参数中的null和undefined
for (const parameter in config.data) {
if (utils.isNull(config.data[parameter]) || utils.isUndefined(config.data[parameter])) {
delete config.data[parameter];
}
}
// 添加token
if (localStorage.token) {
config.headers['x-access-token'] = localStorage.token;
}
if (config.changeHead) {
config.headers['Content-Type'] = 'multipart/form-data';
}
if (config.needFormData) {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
config.data = qs.stringify(config.data);
}
if (JSON.stringify(config.data) === '{}' && config.headers['Content-Type'] !== 'multipart/form-data') {
config.data = null;
}
if (!config.noLoading) {
loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
});
}
return config;
},
(error) => {
Promise.reject(error);
}
);
在上面中,我自己配置了一个ts的接口。这样子不仅仅可以添加config里面的新字段,并且在你设置headers时,如果你不配置any的话。在axios声明config的headers时可能存在未定义
所以自己定义了一个接口,继承axios定义的接口
响应拦截器。在这个拦截器中可以设置一些请求错误的提示信息
service.interceptors.response.use(
(response) => {
if (loading) loading.close();
return response.data;
},
(error) => {
console.log(error.response);
if (loading) loading.close();
if (error.response) {
loading.close();
return handlerError(error);
} else {
loading.close();
ElMessage({
message: error,
type: 'error',
});
}
}
);
function handlerError(error: any) {
if (error && error.response) {
if (error.response.status === 400) {
error.message = '请求错误';
} else if (error.response.status === 401) {
// 当服务端返回401状态码的时候,2秒后跳转登录页
error.message = '未授权,请登录';
window.location.href = '/#/login';
} else if (error.response.status === 403) {
// 无权限 TODO
error.message = '拒绝访问';
window.location.href = '/#/403';
} else if (error.response.status === 404) {
// not found TODO
// window.location.href = "/#/404";
error.message = `请求地址出错: ${error.response.config.url}`;
} else if (error.response.status === 408) {
error.message = '请求超时';
} else if (error.response.status === 500) {
error.message = error.response.data.message || '服务器内部错误';
} else if (error.response.status === 501) {
error.message = '服务未实现';
} else if (error.response.status === 502) {
error.message = '网关错误';
} else if (error.response.status === 503) {
error.message = '服务不可用';
} else if (error.response.status === 504) {
error.message = '网关超时';
} else if (error.response.status === 504) {
error.message = 'HTTP版本不受支持';
} else {
error.message = `连接出错(${error.response.status})!`;
}
ElMessage({
message: error.response.data.errMsg || error.message || '出现错误,请稍后再试',
type: 'error',
});
}
return Promise.reject(error);
}
我们将两个拦截器配置好了以后,就可以在封装一些请求的方法暴露出去。比如POST
export const POST = (url: string, params: any, config?: any) => {
return service.post(url, params, config).then((res) => res);
};
然后我们在src目录下面创建一个api文件夹,这个文件夹就是管理我们项目中所有的请求api链接 比如我们创建一个登录文件,在里面写上请求的地址和方法
import * as API from '@/utils/request';
interface LOGINPARAMS {
username: string;
password: string;
}
export default {
login: (params: LOGINPARAMS) => API.POST('/adm/v1/sessions', params),
};
这样子我们的axios就轻松的封装完毕。。。开心!!!!!!!!!!!!!!!