日常编码中,对于接口,我们一般会使用axios库进行访问。而通常,我们还需要对axios进行二次封装。因为往后的写代码会越来越多,而需要访问的接口也会越来越多,我们阔以把所有需要的接口都封装在一个文件夹中,当需要的时候,我们只需要引入提交封装好的接口模块就可以了,而不需要每个文件夹都去做繁琐、重复的操作。这样,对于我们后期维护比如修改接口参数地址等也会会变得十分方便,所以二次封装是有必要的。
那么我们在进行二次封装时就可以提前把以后可能发生,或者一定需要的一些内容定义好。下面就教大家一个二次封装需要的一些基本配置。
import axios from "axios"
import qs from "qs"; // 转换格式用
// 使用接口的环境有三种,开发环境、测试环境、生产环境
/*
*根据环境变量去区分接口的默认地址
*/
switch (process.env.NODE_ENV) {
case "production":
axios.defaults.baseURL = "http://api.zhufengpeixun.cn"; // 生产环境下调用的接口(部署在服务器上的环境)
break;
case "test":
axios.defaults.baseURL = "http://192.168.20.12"; // 测试环境下调用的接口
break;
case "development":
// axios.defaults.baseURL = "http://localhost:3000"; // 开发环境下调用的接口(本地服务器)
axios.defaults.baseURL = "/api"; // 跨域需要
}
/*
*设置超时时间和跨域是否携带凭证 -- token
*/
axios.defaults.timeout = 10000; // 设置超时时间 --- 10秒
axios.defaults.withCredentials = true; // 设置CORS允许跨域过程携带资源凭证, 让cookie能够传递过去 (登录校验需要走sessin和cookie)
/*
*一般的传参格式都是 xxx = xxx & xxx = xxx 或者 x-www-from-urlencoded
*设置post的请求头,告诉服务器请求主体的数据格式(转为上面第二种)
*是否转换,看服务器要求什么格式
*/
axios.defaults.headers["Content-TYpe"] == "application/x-www-from-urlencoded"; // 声明我传给你的是这种格式
/*
*改变请求主体格式,transformRequest(翻译:请求预处理函数) --- 只对post请求有作用
*接收的参数data,post请求时向请求主体传的东西
*对于post请求,将传进俩的格式变成这种请求
*qs.stringify(data) --- 将x-www-from-urlencoded 变为 xxx = xxx & xxx = xxx 格式
*qs --- 第三方库,转换用的
*/
axios.defaults.transformRequest = data => { qs.stringify(data) } // 是否要转需要的格式视服务器需要而定
/*
*设置请求拦截器
* 正常发请求为: 客户发送请求 -> 服务器接收请求
* 拦截器: 客户端发送请求 -> 拦截处理请求再发给服务器 -> 服务器接收请求
*
* TPKEN校验(JWT) --- 令牌、凭证。当第一次向服务器发请求,服务器会通过算法给我们一个和客户端建立连接的标识(TOKEN)
* 要求客户端以后每次向服务器发请求都需要把TOKEN值带上传给服务器,服务器每次接到其他请求进行处理时首先验证TOKEN,
* 看TOKEN值是否和之前计算的规则是否一样,如果一样则为正常、合法的访问。如何不符合则返回以一个状态码,告诉我们是非法访问,没有权限的。
* 或者TOKEN会过期,当我们发送了过期的TOKEN,服务器也是不会正常处理我们的请求,而是返回有个TOKEN过期,告诉我们该怎么做。
* 现在接口请求一般都会携带TOKEN进行校验,保障每次请求的安全性和准确性。
* 处理TOKEN做法:接收服务器返回的TOKEN,存储到vx/redux/本地存储,每次发送请求都需要将Token带上,否则服务器会认为你是非法访问。
* TOKEN失败的话,把TOKEN清掉,重新获取TOKEN
*/
axios.interceptors.request.use(config => {
// 获取token --- 可以是vx/localstorage/cookie
const token = localStorage.getItem("token");
// // 携带token --- 将token放在请求头中
token && (config.headers.Authorization = token);
return config;
}, error => {
// 请求失败返回失败
return Promise.reject(error);
});
/*
*响应拦截器
* 拦截器: 服务器返回信息 -> 响应处理请求再返回客户端 -> 客户端接收数据
* 响应状态码,服务器返回200才算成功,2开头的走requset,其余的都走error
* 3开头的也算成功3开头的不是永久重定向,而是临时重定向,走的是协商缓存
* (很多公司都不配,因为很多公司接口处理一般很少出现3开头的,一般都是资源文件出现3)
*/
axios.defaults.validateStatus = status => {
// 自定义响应成功的HTTP状态码,自己设置只要是返回状态码是2和3开头的都走request,否则走error
return /^(2|3)\d{2}$/.test(status);
}
axios.interceptors.response.use(response => {
// 在响应后直接拿到主体数据 (看个人需要而定)
return response.data;
}, error => {
/*
* 走这里说明响应状态码不是2开头的
* 即使返回错误,error也能够拿到返回的response
*/
const { response } = error;
if (response) { // 服务器返回了结果,
switch (response.status) { // 对返回不同的状态码进行不同的处理
case 401: // 返回401代表没有访问权限(一般是没有登录)
break; // 此时可以做的操作:跳转到可以登录的地方,或者弹出一个提示的蒙层(比如用element组件库中的模板:this.$message)
case 403: // 返回403代表访问成功,但是服务器拒绝执行(一般是TOKEN过期,session过期有时也会走)
break;
case 404: // 找不到请求的地址, 当前请求的地址有问题(找不到页面)
break;
}
} else { // 服务器连结果都没有返回给你,有两种原因:服务器崩了(一般返回状态码为500) || 客户端没有网(没网的话连接不了服务器所以不会返回)
if (!window.navigator.onLine) { //断网了
// 断网处理: 可以跳转到断网页面,让用户再刷新(可以在服务器做一个断网页面,在此页面提示用户当前没有连接网络);
// 阔以跳转路由(导入router) || localtion.href = "/" 来跳转,(把当前页面传递给断网页面,等连接网络后再跳转回来)
return;
}
// 到这里说明是服务器的问题,直接返回报错问题
return Promise.reject(error);
}
})
/*
*params:{phone:[String, Number], password: String}
*登录需要:手机号,密码
*/
async function login(params) {
return await axios.get("/login/cellphone", { params });
}
export { login }
总结一些,axios二次封装是我们在项目开发中需要使用的,也是必不可少的,这门功课学好,与我们而言绝对是有实质性的帮助,以上就是二次封装需要的一些基本配置了
希望能够有所帮助!