概述
在现在的前端开发当中,如果是工程化项目,多数是基于框架的脚手架进行开发的,因此在数据请求这方便,使用最普遍的就是axios了,axios的好处不仅仅是简化了我们网络请求的代码量,还提供了网络请求拦击,响应拦截等等功能,因此在项目中我们比不可少会使用axios来封装我们自己请求。
实现
import Vue from 'vue';
import Axios from 'axios';
import qs from 'qs';
// axios 实例对象(项目中如果多个接口地址配置不一样,就需要实例化出axios对象,一个接口域名配置一样的话无所谓)
const axios = Axios.create();
//请求超时实现
axios.defaults.timeout = 60000;
//接口域名地址:例如https://etextbook.hep.com.cn:50000/UserOnline/Search,baseURL为https://etextbook.hep.com.cn:50000
axios.defaults.baseURL = https://etextbook.hep.com.cn:50000;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
// 请求拦截器
axios.interceptors.request.use(
async config => {
// 添加功能请求参数
let requestData = Vue.prototype.baseRequestData(config);
//声明验签参数,通过将接口请求参数通过算法加密给后端验签使用(根据自己项目需求来)
let token = '';
//当接口返回值类型不是二进制数据(例如不是音视频)
if (config.responseType !== 'arraybuffer') {
//js接收返回值的时候,可能会出现大数精度丢失的情况,这里需要处理下
config.transformResponse = [
function (data) {
// 对 data 进行任意转换处理
const par = /([^\\]{1}[":]{2}[ \[]{0,2})([\d]{16,})([\r\n},\]]{1})/g;
let responseText = data;
const arrReg = /\[((\d,)*\d)*\]/g;
responseText = responseText.replace(arrReg, match => {
if (match.length > 2) {
return (
match.charAt(0) +
match.slice(1, match.length - 1).replace(/([\d]{16,})/g, '"$1"') +
match.charAt(match.length - 1)
);
} else {
return match;
}
});
responseText = responseText.replace(par, '$1"$2"$3');
return JSON.parse(responseText);
},
];
}
//post请求
if (config.method === 'post') {
//请求参数是formmDta类型(例如文件上传),需要模板form表单,避免post请求参数丢失
if (config.data instanceof FormData) {
const data = Vue.prototype.baseRequestData(config);
for (let key in data) {
config.data.append(key, data[key]);
}
} else {
//普通post请求
requestData = Vue.prototype.$deleteKey(Object.assign({}, Vue.prototype.baseRequestData(config), config.data));
token = Vue.prototype.$setToken(requestData);
config.data = qs.stringify(Object.assign({}, requestData, { X_Public_Token: token }));
}
} else if (config.method === 'get') {
//get请求
requestData = Vue.prototype.$deleteKey(Object.assign({}, Vue.prototype.baseRequestData(config), config.params));
token = Vue.prototype.$setToken(requestData);
config.params = Object.assign({}, requestData, { X_Public_Token: token });
}
return config;
},
err => {
return Promise.reject(err);
},
);
// http 相应拦截器
/**
* 拦截器也可以判定返回的response成功时的状态码进行拦截
*/
axios.interceptors.response.use(
async res => {
//我的接口返回的字段我可以根据这个标识来判断请求成功或者是吧,然后做些全局提示等等
if (!res.data.Success) {
switch (parseInt(res.data.Code)) {
case 34:
//状态码34(我这代表未登录,返回首页,自己根据接口来判断)
await Vue.prototype.$logoutSystem();
break;
}
//请求失败全局提示
Vue.prototype.$Message.error(res.data.Description);
}
return res;
},
error => {
if (error.response) {
switch (error.response.status) {
case 500:
//状态码500的时候,服务端错误
Vue.prototype.$Message.error('服务端错误');
}
}
},
);
export default axios;