以vue项目为例,介绍
ts
版配置axios
的问题。
./package.json 中用到了axios
。UI随意,这里用了element-plus
{
...
"dependencies": {
...
"element-plus": "^1.0.1-beta.21",
...
"axios": "^0.21.1",
...
},
...
}
新增 /src/api/request.ts 文件。
import axios, {AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios';
import { ElMessage } from 'element-plus'
export class Request {
public static axiosInstance: AxiosInstance;
// constructor() {
// // 创建axios实例
// this.axiosInstance = axios.create({timeout: 1000 * 12});
// // 初始化拦截器
// this.initInterceptors();
// }
public static init() {
// 创建axios实例
this.axiosInstance = axios.create({
baseURL: process.env.VUE_APP_BASE_URL + '/api/v1',
timeout: 6000
});
// 初始化拦截器
this.initInterceptors();
// return axios;
}
// 为了让http.ts中获取初始化好的axios实例
// public getInterceptors() {
// return this.axiosInstance;
// }
// 初始化拦截器
public static initInterceptors() {
// 设置post请求头
this.axiosInstance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
/**
* 请求拦截器
* 每次请求前,如果存在token则在请求头中携带token
*/
this.axiosInstance.interceptors.request.use(
(config: AxiosRequestConfig) => {
// const token = Vue.ls.get(ACCESS_TOKEN)
// if (token) {
// config.headers['Authorization'] = 'Bearer ' + token
// }
// 登录流程控制中,根据本地是否存在token判断用户的登录情况
// 但是即使token存在,也有可能token是过期的,所以在每次的请求头中携带token
// 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码
// if (config.headers.isJwt) {
const token = localStorage.getItem('ACCESS_TOKEN');
if (token) {
config.headers.Authorization = 'Bearer ' + token;
}
// }
return config;
},
(error: any) => {
console.log(error);
},
);
// 响应拦截器
this.axiosInstance.interceptors.response.use(
// 请求成功
(response: AxiosResponse) => {
// if (res.headers.authorization) {
// localStorage.setItem('id_token', res.headers.authorization);
// } else {
// if (res.data && res.data.token) {
// localStorage.setItem('id_token', res.data.token);
// }
// }
if (response.status === 200) {
// return Promise.resolve(response.data);
return response;
} else {
Request.errorHandle(response);
// return Promise.reject(response.data);
return response;
}
},
// 请求失败
(error: any) => {
const {response} = error;
if (response) {
// 请求已发出,但是不在2xx的范围
Request.errorHandle(response);
return Promise.reject(response.data);
} else {
// 处理断网的情况
// eg:请求超时或断网时,更新state的network状态
// network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
// 关于断网组件中的刷新重新获取数据,会在断网组件中说明
ElMessage.warning('网络连接异常,请稍后再试!');
}
}
);
}
/**
* http握手错误
* @param res 响应回调,根据不同响应进行不同操作
*/
private static errorHandle(res: any) {
// 状态码判断
switch (res.status) {
case 401:
break;
case 403:
break;
case 404:
ElMessage.warning('请求的资源不存在');
break;
default:
ElMessage.warning('连接错误');
}
}
}
- request.ts 封装了
Request
方法,使用class
语法糖,过程中创建了axiosInstance
- 因为使用了
ts
版,从axios
依赖中引用了AxiosInstance
、AxiosRequestConfig
、AxiosResponse
, 这三个属于接口interface。 Request
类实现中包含创建实例this.axiosInstance
,初始化拦截器,拦截器中包括响应拦截和请求拦截。请求拦截设置了token
,响应拦截处理了错误逻辑。baseURL
中的process.env.VUE_APP_BASE_URL
是通过.env.development 配置得到的。
.env.development
NODE_ENV = 'development'
VUE_APP_BASE_URL='http://0.0.0.0:8899'
对应 ./package.json 中的脚本
{
...
"scripts": {
"serve": "vue-cli-service serve --mode development",
"build": "vue-cli-service build --mode production"
},
...
}
/src/main.ts 中引入了刚创建的request.ts
...
import { Request } from '@/api/request';
const app = createApp(App as any)
Request.init();
...
新增 /src/api/api.ts 文件,随意创建一个 login
的接口进行测试。
import { Request } from './request';
export function login (parameter: any) {
return Request.axiosInstance({
url: '/login',
method: 'post',
data: parameter
})
}
用随便一个页面,比如 /src/views/Home.vue 中
import { defineComponent, onMounted } from 'vue';
import { login } from '@/api/api';
export default defineComponent({
name: 'Home',
setup() {
onMounted(()=>{
login({
username:'admin',
password:'123456'
});
})
}
});
- 用
Composition API
- 引入刚写的
login
接口 - onMounted方法中调用
login
- 可以通过nodejs创建一个
login
接口测试。