最近正在用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的中间件用的好的话,应该没拦截器什么事了。