介绍

网络请求可以说是前端与后端的 ”桥“, 对于一个系统而言,后端的规范必定是统一的,前端所接受的也将是统一的,所以我们只需要配置项目所对应的即可

我们先看看 这块写在哪了?

位置: src/app.tsx 中的 request

为了方便起见 我把他单独拉倒了 utils/Request 文件,方便后续的配置

V4 与 V5 的不同

在 V5 中我们需要在 umi 中引入,而不是在 utils/request.ts 文件中引用,相对于 V4,V5中扩展了一个配置 skipErrorHandler 这个配置是干嘛用的呢,作用是 跳过默认的错误处理,用于项目中特殊的接口

  1. import { request } from 'umi';
  2. request('/api/user', {
  3. params: {
  4. name: 1,
  5. },
  6. skipErrorHandler: true,
  7. });

地址更换

之前讲过,我们在分模块打包时,根据不同的命令,打出不同的包,其中,打包的地址就在这里使用

我们 prefix 来设置接口的域名端口

如:

  1. export const request: RequestConfig = {
  2. prefix: process.env.NODE_ENV === "production" ? host : '/api/',
  3. };

拦截器

每个系统对应的后端的请求方式都不相同,我们应该在 请求前 和 请求后 做一些特定的处理,帮助我们快速开发,比如:在请求的时候 在请求头加上 token

那么谁可以做到呢?V5中有两种方式 中间件(middlewares)和 拦截器,这两种方式都可以优雅地做网络请求前后的增强处理,但中间件使用起来比较复杂,所以这里只介绍拦截器

请求拦截 requestInterceptors

首先,我们来说说请求拦截需要配置什么

  • 后端的不同发送网络的格式,方式都不通,比如说配置 Content-Type
  • 此外,现在大多数项目都会有一个token,用来判断

这里要说明一点 token 通常需要存储到本地的,原因是每次启动项目都会用到,当然缓存能少用就少用,尽量使用数据流做处理。

因此 我们需要设置一个变量来存储 token,这里我单独设置了个文件来存储 src/utils/Setting/storageSy 来作为变量名,

另外我们需要注意一点,在未登录的时候并无token,并且在退出登录后,要清空缓存

废话有点多~ 直接看代码吧~

  1. /**请求拦截 */
  2. export const requestInterceptors: any = (url: string, options: RequestInit) => {
  3. if (storageSy.token) {
  4. const token = `Bearer ` + localStorage.getItem(storageSy.token);
  5. options.headers = {
  6. ...options.headers,
  7. "Authorization": token,
  8. 'Content-Type': 'application/json',
  9. }
  10. }
  11. return { url, options };
  12. }

响应拦截 responseInterceptors

跟请求拦截一样,我们先来说说响应拦截做的的做了什么吧

  • 统一的错误处理,如:在网络不好的情况下,请求不到数据,这时我们可以给一个统一的提示语来告诉用户
  • 统一报错,有的时候返回的状态是不正常的,这时我们就可以做处理,给出接口给的提示语,并且我在这里统一设置了一下,如果返回的不是 200(成功)将统一设置为 false, 这样就不需要用 catch 来进行捕获了。
  • 用户登录时限,一个系统中,我们希望用户登录这个是有时效性,这是接口就回返回特定的状态码,来告诉我们用户信息不匹配,或者登录时间到了,这时我们需要在响应拦截中给出对应的提示,并清空缓存,退出系统

关于第二点,其实有个小问题,就是他什么都不返回,但状态码为 200 ,这时在具体页面中如何判定成功呢,其实只要判定 返回的类型 不等于 布尔值就行了

  1. // 响应拦截
  2. export const responseInterceptors:any = async (response: Response) => {
  3. if (!response) {
  4. notification.error({
  5. description: '您的网络发生异常,无法连接服务器',
  6. message: '网络异常',
  7. });
  8. return;
  9. }
  10. const data = await response.clone().json();
  11. if ([10001,10008].includes(data.resultCode)) {
  12. message.error(data.message);
  13. localStorage.clear();
  14. return false;
  15. }
  16. if (data.code !== 200) {
  17. message.error(data.message);
  18. return false;
  19. }
  20. return data.data ? {...data.data, ...data} : data;
  21. }