介绍
网络请求可以说是前端与后端的 ”桥“, 对于一个系统而言,后端的规范必定是统一的,前端所接受的也将是统一的,所以我们只需要配置项目所对应的即可
我们先看看 这块写在哪了?
位置: src/app.tsx
中的 request
为了方便起见 我把他单独拉倒了 utils/Request
文件,方便后续的配置
V4 与 V5 的不同
在 V5 中我们需要在 umi 中引入,而不是在 utils/request.ts
文件中引用,相对于 V4,V5中扩展了一个配置 skipErrorHandler
这个配置是干嘛用的呢,作用是 跳过默认的错误处理,用于项目中特殊的接口
import { request } from 'umi';
request('/api/user', {
params: {
name: 1,
},
skipErrorHandler: true,
});
地址更换
之前讲过,我们在分模块打包时,根据不同的命令,打出不同的包,其中,打包的地址就在这里使用
我们 prefix 来设置接口的域名端口
如:
export const request: RequestConfig = {
prefix: process.env.NODE_ENV === "production" ? host : '/api/',
};
拦截器
每个系统对应的后端的请求方式都不相同,我们应该在 请求前 和 请求后 做一些特定的处理,帮助我们快速开发,比如:在请求的时候 在请求头加上 token
那么谁可以做到呢?V5中有两种方式 中间件(middlewares)和 拦截器,这两种方式都可以优雅地做网络请求前后的增强处理,但中间件使用起来比较复杂,所以这里只介绍拦截器
请求拦截 requestInterceptors
首先,我们来说说请求拦截需要配置什么
- 后端的不同发送网络的格式,方式都不通,比如说配置 Content-Type
- 此外,现在大多数项目都会有一个token,用来判断
这里要说明一点 token 通常需要存储到本地的,原因是每次启动项目都会用到,当然缓存能少用就少用,尽量使用数据流做处理。
因此 我们需要设置一个变量来存储 token,这里我单独设置了个文件来存储 src/utils/Setting/storageSy
来作为变量名,
另外我们需要注意一点,在未登录的时候并无token,并且在退出登录后,要清空缓存
废话有点多~ 直接看代码吧~
/**请求拦截 */
export const requestInterceptors: any = (url: string, options: RequestInit) => {
if (storageSy.token) {
const token = `Bearer ` + localStorage.getItem(storageSy.token);
options.headers = {
...options.headers,
"Authorization": token,
'Content-Type': 'application/json',
}
}
return { url, options };
}
响应拦截 responseInterceptors
跟请求拦截一样,我们先来说说响应拦截做的的做了什么吧
- 统一的错误处理,如:在网络不好的情况下,请求不到数据,这时我们可以给一个统一的提示语来告诉用户
- 统一报错,有的时候返回的状态是不正常的,这时我们就可以做处理,给出接口给的提示语,并且我在这里统一设置了一下,如果返回的不是 200(成功)将统一设置为 false, 这样就不需要用
catch
来进行捕获了。 - 用户登录时限,一个系统中,我们希望用户登录这个是有时效性,这是接口就回返回特定的状态码,来告诉我们用户信息不匹配,或者登录时间到了,这时我们需要在响应拦截中给出对应的提示,并清空缓存,退出系统
关于第二点,其实有个小问题,就是他什么都不返回,但状态码为 200 ,这时在具体页面中如何判定成功呢,其实只要判定 返回的类型 不等于 布尔值就行了
// 响应拦截
export const responseInterceptors:any = async (response: Response) => {
if (!response) {
notification.error({
description: '您的网络发生异常,无法连接服务器',
message: '网络异常',
});
return;
}
const data = await response.clone().json();
if ([10001,10008].includes(data.resultCode)) {
message.error(data.message);
localStorage.clear();
return false;
}
if (data.code !== 200) {
message.error(data.message);
return false;
}
return data.data ? {...data.data, ...data} : data;
}