axio的请求异常响应统一处理

项目使用了飞冰框架(react),后端是springMVC.

  1. 首先在原生的axios基础上,根据项目要求来改写axios的请求头:
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结构,大致分为两种情况:

  1. 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,
      });
    });
    //失败异常统一处理过了
  };

特别的,此类型的异常信息的处理可避免后端异常尴尬的直接显示到页面,在项目里面必不可少。

以上。

欢迎各位讨论指正。

你可能感兴趣的:(笔记,axios)