Web📌packages📌axios.txt
文档参考:
https://axios-http.com/
https://github.com/axios/axios/
https://www.npmjs.com/package/axios
安装:
npm i axios
使用时通常需要二次封装,对请求和响应做一些统一处理。
========== @/api/http.ts 统一封装请求实例 ==========
import axios from "axios";
const instance = axios.create({
baseURL: "https://mock.apifox.cn/m1/1555493-0-default", //替换成环境变量
timeout: 9000, // 毫秒
});
// 添加请求拦截器
instance.interceptors.request.use(
(cfg) => {
// 在发送请求之前做些什么
cfg.headers = cfg.headers || {}; //严格模式下
cfg.headers["X-Request-Time"] = Date.now().toString();
cfg.headers["Authorization"] = "xxx"; //从stores取值
return cfg; //无需指定content-type,axios会根据传值类型自动添加
},
(err) => {
// 对请求错误做些什么
return Promise.reject(err);
}
);
// 添加响应拦截器
instance.interceptors.response.use(
(res) => {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return res.data; //这里只取body体内容
},
(err) => {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(err);
}
);
export default {
get<T>(url: string, data = {}): Promise<T> {
return instance.request({
method: "get",
url: url,
params: data,
});
},
post<T>(url: string, data = {}): Promise<T> {
return instance.request({
method: "post",
url: url,
data: data,
});
},
put<T>(url: string, data = {}): Promise<T> {
return instance.request({
method: "put",
url: url,
data: data,
});
},
delete<T>(url: string, data = {}): Promise<T> {
return instance.request({
method: "delete",
url: url,
params: data,
});
},
};
========== @/api/errors.ts 定义错误处理方法 ==========
import { AxiosError, AxiosResponse } from "axios";
// 不同接口的错误提示方式有所不同,所以抽出来手动控制。也可在响应拦截器统一处理。
const errorMsg = (err: AxiosError) => {
if (err === undefined || err.response === undefined || err.code === "ERR_NETWORK") {
console.error("网络错误"); //替换成UI框架的弹出消息提示
return;
}
const {
status,
statusText,
data: { msg },
} = <AxiosResponse>err.response;
if (status === 401) {
console.warn("登录已失效"); //替换成提示并跳转登录页
return;
}
if (status < 500) {
console.warn(`(${status}) ${msg || statusText}`);
} else {
console.error(`(${status}) ${msg || "服务器开小差啦"}`);
}
};
//401回登录页,其余显示错误页
const errorPage = (err: AxiosError) => {
if (err === undefined || err.response === undefined || err.code === "ERR_NETWORK") {
console.info("show error");
return;
}
const {
status,
statusText,
data: { msg },
} = <AxiosResponse>err.response;
switch (status) {
case 401:
console.info("show 401");
break;
case 403:
console.info("show 403");
break;
case 404:
console.info("show 404");
break;
default:
if (status < 500) {
console.info("show warn",`(${status}) ${msg || statusText}`);
} else {
console.info("show 500");
}
}
};
export default {
errorMsg,
errorPage,
};
========== @/api/index.ts 单一入口导出所有api接口 ==========
import * as models from "models";
import errors from "./errors";
import http from "./http";
export default {
...errors,
captcha: () => http.get<models.CaptchaResp>("/captcha"), //获取验证码
login: (data: models.LoginArgs) => http.post<models.LoginResp>("/user/login", data), //登录
};
========== @/api/models/xxx.ts 请求响应结构定义 ==========
//也可用namepace代替module,也可用interface代替type,也可逐个export导出
declare module "models" {
type CaptchaResp = {
session_key: string;
base64_image: string;
};
type LoginArgs = {
username: string;
password: string;
session_key: string;
captcha: string;
};
type LoginResp = {
token: string;
username: string;
authority: Authority;
};
}
declare module "models" {
type Authority = { [key: string]: number };
}
========== ========== 使用 ========== ==========
import api from "@/api";
import { LoginArgs } from "models";
const data: LoginArgs = {
username: "admin",
password: "123456",
session_key: "xxxxxx",
captcha: "kcnh",
};
api
.login(data)
.then((res) => {
console.log(res.token);
})
.catch(api.errorMsg); //或 .catch((err) => { api.errorMsg(err); });