umi-request的封装

9,417 阅读1分钟

最近正在用React做项目,之前用vue比较多,对react的了解较少,记录一下学习过程。因为框架用的是Umi,自带的网络请求库是umi-request,参考antd-pro,下面写一下网络请求的封装函数。

项目背景

  • 使用create umi的简单app模板
  • antd

配置request请求时的默认参数

/src/utils/request.js

import { extend } from 'umi-request';
import { getToken } from '@/utils/token';
const baseUrl = process.env.NODE_ENV === 'production' ? '' : '/api';

const request = extend({
  errorHandler, // 默认错误处理
  prefix: baseUrl,
  // 默认请求头
  headers: {
    Authorization: getToken() ? `Bearer ${getToken()}` : null, // 携带token
  },
  credentials: 'include', // 默认请求是否带上cookie
});
// code...
export default request;

异常处理程序

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

const errorHandler = error => {
  const { response = {} } = error;
  const errortext = codeMessage[response.status] || response.statusText;
  const { status, url } = response;

  notification.error({
    message: `请求错误 ${status}: ${url}`,
    description: errortext,
  });
};

这个异常处理程序是处理HTTP响应状态的异常,就是状态码为4xx或5xx等,如果想在响应体自定义错误码,应该在response拦截器里处理,或用中间件。

request拦截器

request.interceptors.request.use((url, options) => {
  return {
    options: {
      ...options,
    },
  };
});

这个request拦截器什么都没有做。我尝试在options里覆盖配置,例如修改headers,发现没有作用?在extend写默认参数就会生效。
可以在这里修改url:

options: {
      ...options,
      url: '/v1'+url
    },

response拦截器

request.interceptors.response.use(async response => {
  // 克隆响应对象做解析处理
  // 这里的res就是我们请求到的数据
  const res = await response.clone().json();
  const { code, message } = res;
  if (code !== 0) {
    console.log('error', res);
    notification.error({
      message: '请求错误',
      description: `${code}: ${message}`,
    });
    // 在处理结果时判断res是否有值即可
    return;
  }
  return res;
});

注意:要获取response.data,必须对response对象进行解析。查看umi-request的issues,说是response对象只能被解析一次,需要克隆一份,因此要response.clone().json()
接下来就可以根据自定义的code进行错误处理。例如,可以设置当code===5008时,提示未登录,然后重定向到登录页;当code!==0时,提示错误信息,然后return,在request函数被调用时,判断结果是否有值再执行对应的代码。
最后,如果不需要进行错误处理,返回res

一些感想

react上手比vue难好多啊,主要是我太菜了。对比axios,感觉umi-request没有那么直观,axios写拦截器就完了。但是umi-request的中间件用的好的话,应该没拦截器什么事了。