umi-request的二次封装(针对后端接口返回错误)

我的代码对于网络上二次封装的是一样的,因为我也是百度学习完后直接搬过来的,
但毕竟网上的代码更适合于他们自己的系统,自己要想好好使用,总会有各种差错不适合自己的,所以针对自己公司的项目进行了修改
主要针对以下两点

  • 后端接口返回4或者5开头的错误进行拦截,进入catch中
  • 后端返回204状态码,直接为空,什么都没有

第一个问题:错误拦截

umi-request中配置了一个errorHandler,用于收集错误信息,以及消息提醒
最后很多时候依然是return response,这样就会导致只是对错误进行提示,但依旧走了then方法里边的后续逻辑
这个时候我的建议是修改为return Promise.reject(error);
就能更好将返回体抛出到error中,不需要再做一系列的判断进行逻辑执行

第二个问题:204返回为空

可能很多人不能理解什么叫做返回为空
官方解释状态码204:成功返回但没有数据
或者直接截图展示一下会更好理解

204的请求与响应

204响应预览

这个情况会发生在我新增,编辑,删除的时候,也会发生在我的查询列表没有数据的时候
如果我依旧是返回response
就会在我的逻辑代码中报错,response不是我想要的格式,处理不了
这个时候如果后端比较好商量且愿意帮你改的话,就告诉他没有什么可返回的,就返回一个空数组或者随便返回一个
如果后端靠不住的,只能自己来了,但我觉得这样的代码不太优雅
204不优雅解决

下来重点 看全部代码吧!!!!

import { extend } from 'umi-request';
import { notification } from 'antd';
import { history } from 'umi';
// import { getAccessToken, clearTokens } from './token'
// import stringUtil from '@/utils/stringUtil'

const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队(异步任务)。',
  204: '删除数据成功。',
  400: '发出的请求体有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  405: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。',
};

let messageFlag = false
/**
 * 异常处理程序
 */
const errorHandler = (error) => {
  const { response } = error;
  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;
    // 处理参数问题
    let noParamUrl = url;
    if (url.indexOf('?') !== -1) {
      noParamUrl = url.substring(0, url.indexOf('?'));
    }

    // 如果调用接口去获取token报错,则证明是账号有误
    if (url.indexOf('/login/account') !== -1) {
      notification.error({
        // message: `请求错误 [20002]: ${noParamUrl}`,
        message: '账号不存在或密码错误',
        // description: '账号不存在或密码错误',
      });
      return response;
    }

    if (status === 401) {
      notification.warn({
        message: '请重新登陆!',
      });
      clearTokens();
      history.push('/gp/login');
    } else {
      notification.error({
        message: `请求错误 [${status}]: ${noParamUrl}`,
        description: errorText,
      });
    }
  } else if (!response) {
    notification.error({
      description: '您的网络发生异常,无法连接服务器',
      message: '网络异常',
    });
  }
  return Promise.reject(error);
};

/**
 * 配置request请求时的默认参数
 */
const request = extend({
  prefix: '/api',// 路径前缀
  errorHandler, // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
  timeout: 6000,
});

/**
 * 所以请求拦截器
 */
request.interceptors.request.use((url, options) => {
  return {
    url,
    options: {
      ...options,
      // headers: {
      //   Authorization: getAccessToken(),
      // },
    },
  };
});

/**
 * 所有响应拦截器
 */
request.interceptors.response.use(async (response, options) => {
  console.log(response);
  const { url, status } = response;
  const { method, params } = options
  // 获取token的接口,正确返回直接放过
  if (url.indexOf('/system/oauth/token') !== -1) {
    return response;
  }

  // 返回下载流的问题,可以在url添加标识
  if (url.indexOf('/download/') !== -1) {
    if (status !== 200) {
      notification.error({
        message: `下载出错 : ${url}`,
      });
    } else {
      return await response.clone().blob();
    }
    return null;
  }

  if (parseInt(status / 100) == 2 && status % 100 > 0) {
    return undefined
  }

  // const data = await response.clone().json();
  // console.log(data)
  // if ((parseInt(status / 100) !== 2 && data.code !== 0)) {
  //   notification.error({
  //     message: data.message,
  //   });
  // }

  return response;
});

export default request;

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容