1.封装目的
- 实现请求拦截
- 实现响应拦截
- 常见错误信息处理
- 请求头设置
- api 集中式管理
2.初始化 axios 实例
虽然 axios 可以调用 get、post 等方法发起请求,但是我们为了更好的全局控制所有请求的相关配置,所以我们使用 axios.create()创建实例的方法来进行相关配置,这也是封装 axios 的精髓所在。
示例代码:
// 创建 axios 请求实例
const serviceAxios = axios.create({
baseURL: "", // 基础请求地址
timeout: 10000, // 请求超时设置
withCredentials: false, // 跨域请求是否需要携带 cookie
});
通过 create 方法我们得到了一个 axios 的实例,该实例上有很多方法,比如拦截器等等。我们创建实例的时候可以配置一些基础设置,比如基础请求地址,请求超时等等。
3.设置请求拦截
我们在发送请求的时候可能需要携带一些信息在请求头上,比如 token 等,所以说我们就需要将请求拦截下来,处理一些我们的业务逻辑。
示例代码:
// 创建请求拦截
serviceAxios.interceptors.request.use(
(config) => {
// 如果开启 token 认证
if (serverConfig.useTokenAuthorization) {
config.headers["Authorization"] = localStorage.getItem("token"); // 请求头携带 token
}
// 设置请求头
if(!config.headers["content-type"]) { // 如果没有设置请求头
if(config.method === 'post') {
config.headers["content-type"] = "application/x-www-form-urlencoded"; // post 请求
config.data = qs.stringify(config.data); // 序列化,比如表单数据
} else {
config.headers["content-type"] = "application/json"; // 默认类型
}
}
console.log("请求配置", config);
return config;
},
(error) => {
Promise.reject(error);
}
);
我们通过调用 axios 的实例方法来进行请求拦截。
4.设置响应拦截
axios 请求的返回结果里面包含了很多东西,我们的业务层面通常只需要后端返回的数据即可,所以我们需要设置相应拦截,在响应结果返回给业务层之前做一些操作。
示例代码:
// 创建响应拦截
serviceAxios.interceptors.response.use(
(res) => {
let data = res.data;
// 处理自己的业务逻辑,比如判断 token 是否过期等等
// 代码块
return data;
},
(error) => {
let message = "";
if (error && error.response) {
switch (error.response.status) {
case 400:
message = "参数不正确!";
break;
case 401:
message = "您未登录,或者登录已经超时,请先登录!";
break;
default:
message = "异常问题!";
break;
}
}
return Promise.reject(message);
}
);
完整文件
import axios from "axios";
import request from "request";
// 创建 axios 请求实例
const serviceAxios = axios.create({
baseURL: ----------, // 基础请求地址
timeout: 10000, // 请求超时设置
withCredentials: false, // 跨域请求是否需要携带 cookie
});
// 创建请求拦截
serviceAxios.interceptors.request.use(
(config) => {
// 如果开启 token 认证
if (serverConfig.useTokenAuthorization) {
config.headers["Authorization"] = localStorage.getItem("token"); // 请求头携带 token
}
// 设置请求头
if(!config.headers["content-type"]) { // 如果没有设置请求头
if(config.method === 'post') {
config.headers["content-type"] = "application/x-www-form-urlencoded"; // post 请求
config.data = qs.stringify(config.data); // 序列化,比如表单数据
} else {
config.headers["content-type"] = "application/json"; // 默认类型
}
}
console.log("请求配置", config);
return config;
},
(error) => {
Promise.reject(error);
}
);
// 创建响应拦截
serviceAxios.interceptors.response.use(
(res) => {
let data = res.data;
// 处理自己的业务逻辑,比如判断 token 是否过期等等
// 代码块
return data;
},
(error) => {
let message = "";
if (error && error.response) {
switch (error.response.status) {
case 400:
message = "参数不正确!";
break;
case 401:
message = "您未登录,或者登录已经超时,请先登录!";
break;
default:
message = "异常问题!";
break;
}
}
return Promise.reject(message);
}
);
export default serviceAxios;
接口调用示例代码:
import serviceAxios from "../index";
// 统一管理api
const user= {
userApi:"/api/website/queryMenuWebsite"
loginApi:"/api/user/login"
}
export default user
export function getUserInfo(params) {
return serviceAxios({
url: user.userApi,
method: "post",
params,
});
};
export function login(data){
return serviceAxios({
url: user.loginApi,
method: "post",
data,
});
};
请求拦截里面针对 token 进行处理
响应拦截里面判断 token 是否过期等等
在请求拦截里面根据业务场景修改请求头
在拦截里面设置全局请求进度条等等