项目使用了飞冰框架(react),后端是springMVC.
import axios from 'axios';
import urlparse from 'url-parse';
// 使用crypto-js加密库进行md5加密
import MD5 from 'md5';
import { Message } from '@alifd/next';
import ErrorMsg from './errorMsg';
/**
* 拦截 axios,
* 对请求异常信息,做统一处理,如果成功,则不做处理,继续向下进行
*/
// 根url
axios.defaults.baseURL = window.baseUrl;
axios.create({
timeout: 10000, // 请求超时时间
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
// },
});
// 开始请求设置(请求我们不做处理,如果有特殊需求,可在此统一处理),发起拦截处理
axios.interceptors.request.use((config) => {
// 得到参数中的requestname字段,用于决定下次发起请求,取消相应的 相同字段的请求
// post和get请求方式的不同,使用三目运算处理
let tokenParams = {};
tokenParams = (config.params || config.data) ? (config.params || config.data) : {};
var paramsStr=JSON.stringify(tokenParams)
let paramsStrMD5=MD5(paramsStr)
// 判断,如果这里拿到上一次的requestName,就取消上一次的请求
// if (requestName) {
// if (axios[requestName] && axios[requestName].cancel) {
// axios[requestName].cancel();
// }
// config.cancelToken = new CancelToken((c) => {
// axios[requestName] = {};
// axios[requestName].cancel = c;
// });
// }
const currentLocation = location.toString();
const urlPars = urlparse(currentLocation, true);
// 截取参数#以后的数据
const route = urlPars.hash.substring(1);
config.headers.currentRoute = route;
//token用来避免重复提交,这里的业务背景是增删改查数据时的重复提交问题,
//与后端协商用请求头的token(自定义的变量名称),来辨别,如果当前请求存在,
//后端将给出一个'不可重复提交'的异常信息。
config.headers.token=paramsStrMD5;
// console.log('config', config);
return config;
}, (error) => {
return Promise.reject(error);
});
// respone拦截器 我们主要拦截异常,对异常信息统一处理
axios.interceptors.response.use(
(response) => {
return response;
},
(error) => {
// 异常信息统一处理1),直接给出异常提示
// const errMsg = ErrorMsg(error.response);
// Message.show({
// type: 'error',
// title: '错误信息',
// closeable: true,
// duration: 0,
// content: errMsg,
// });
//异常处理2)调用统一异常函数
ErrorMsg(error.response);
return Promise.reject(error);
}
);
export default axios;
2.下面介绍处理异常的文件errorMsg.js
特别的介绍下,后端的response结构,大致分为两种情况:
- axios请求成功,即code为200时:
{
"status":"SUCCESS",
"message":null,
"data":{
"commResult":Array[]
},
"code":200,
"errorMsg":null
}2.axios请求完成,status为非200时:
{
"status":"***",
"message":null,
"code":403/302/204/203,//此处可与后端根据http协议,统一协定。
"errorMsg":null
}代码如下:
import { Message } from '@alifd/next';
/**
* 异常信息统一处理,包括axios请求,以及databinder方式请求
* errorResponse,请求错误的error.response
*/
const ErrorMsg = (errorResponse) => {
//errorResponse来自ErrorMsg(error.response)
let msgTitle='错误信息';
let visible=true;
// 异常统一处理(包括后台校验不通过的,权限不足访问的)
// 初始化异常信息 提取异常信息
let errMsg = '';
if (typeof errorResponse !== 'undefined' && typeof errorResponse.data !== 'undefined' && errorResponse.data) {
const errordata = errorResponse.data;
// 异常状态码
const errorCode = errordata.code;
if (typeof errorCode !== 'undefined' && errorCode) {
// 储存校验异常信息有个地方 一个是actionErrorList 一个是fieldErrorMap
// 状态码为403 说明是校验异常
// 循环获取actionErrorList中的异常信息
if (errorCode === 403) {
visible=true;
// 获取自定义校验异常信息
const actErrors = errordata.errorMsg.actionErrorList;
if (typeof actErrors !== 'undefined' && actErrors && actErrors.length > 0) {
for (let i = 0; i < actErrors.length; i++) {
errMsg += actErrors[i];
errMsg += ' ';
}
}
// 循环获取actionErrorList中的异常信息(一般是表单校验)
const fieldErrorMap = errordata.errorMsg.fieldErrorMap;
if (typeof fieldErrorMap !== 'undefined' && fieldErrorMap) {
for (const fielerr in fieldErrorMap) {
// errMsg += fielerr;
// errMsg += ':';
errMsg += fieldErrorMap[fielerr];
errMsg += ' ';
}
}
} else if (errorCode === 302) {
//用户未登录
visible=true;
msgTitle='';
errMsg += errordata.errorMsg;
const toUrl = `${window.baseUrl2}`;
//定位到登录页面
location.href = `${toUrl}user/login`;
} else if (errorCode === 203) {
// 用户没有访问页面的权限
visible=false;
// errMsg += errordata.errorMsg;
const toUrl = `${window.baseUrl2}`;
const currentUrl = location.toString();
if (currentUrl !== `${toUrl}exception/203`) {
location.href = `${toUrl}exception/203`;
}
} else if (errorCode === 204) {
visible=false;
// 用户请求接口的权限
// errMsg='无查询权限';
// msgTitle='';
console.log('用户请求无权限,异常为:',errorResponse)
}
}
}
if (errMsg === '' || !errMsg) {
// 包含:接口500异常提示信息处理
console.log('此时errorMsg为空', errorResponse);
errMsg = '系统异常,请稍后再试';
}
// 显示出错误信息
if(visible||errorResponse==='undefined'||errorResponse.data===null){
Message.show({
type: 'error',
title: msgTitle,
closeable: true,
duration: 0,
content: errMsg,
});
}
};
export default ErrorMsg;
3.axios在项目中的使用:
import axios from '../../../../commonAxios/server';
axios({
method: 'POST',
url: 'url',
data: items,
}).then((res) => {
//请求成功的操作
********
//自定义的成功提示
Message.success({
title: '保存数据项',
duration: 0,
content: '保存成功,请刷新页面',
closeable: true,
});
});
//失败异常统一处理过了
};
特别的,此类型的异常信息的处理可避免后端异常尴尬的直接显示到页面,在项目里面必不可少。
以上。
欢迎各位讨论指正。