![acf34f806dcd9fc742312c1d11dd5231.png](https://i-blog.csdnimg.cn/blog_migrate/7234c6e065c1e55d2c9cb5b13ea8bd6c.jpeg)
最近参照antd-pro脚手架进行开发,因此接触到了umi-request。
umijs/umi-requestgithub.com![e840b37678ad4fdd504a700d90f9f7a7.png](https://i-blog.csdnimg.cn/blog_migrate/bcc5689b1fffb33dab4e195bded4782a.png)
umi-request对fetch进行了封装,简化了api的使用,结合了fetch和axios的特点,具体可参照umi-request的readme介绍。
文件结构
核心文件夹为src文件夹,内含
- lib文件夹为修改后的fetch.js;
- defaultInterceptor.js用于注册拦截器;
- index.js是外部调用的入口文件;
- request.js提供request实例;
- utils.js定义了处理缓存、请求异常、响应异常、处理gbk、json语法分析的功能类;
- wrapped-fetch.js从文件名可以看出来为封装fetch,实现更新版数据的传递;
- wrapped-rpc.js从文件可以看出封装了rpc通信,待实现;
代码分析
原始代码里含的注释基本上已经很全面了
defaultInterceptor.js
功能有:数据提交方式简化/针对常见两种数据传输格式补全文件头“Accept: 'application/json', 'Content-Type': 'application/json(或者x-www-form-urlencoded);charset=UTF-8'”/url 参数自动序列化
主要是对传入的url和option进行格式化的处理,以便后续的fetch.js进行处理。
关于option的新增参数参见request.js。
export default (url, originOptions = {}) => {
const options = {
...originOptions };
// 默认get, 兼容method大小写
let method = options.method || 'get';
method = method.toLowerCase();
if (method === 'post' || method === 'put' || method === 'patch' || method === 'delete') {
// requestType 简写默认值为 json
const {
requestType = 'json', data } = options;
// 数据使用类axios的新字段data, 避免引用后影响旧代码, 如将body stringify多次
if (data) {
const dataType = Object.prototype.toString.call(data);
if (dataType === '[object Object]' || dataType === '[object Array]') {
if (requestType === 'json') {
options.headers = {
Accept: 'application/json',
'Content-Type': 'application/json;charset=UTF-8',
...options.headers,
};
options.body = JSON.stringify(data);
} else if (requestType === 'form') {
options.headers = {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
...options.headers,
};
options.body = stringify(data);
}
} else {
// 其他 requestType 自定义header
options.headers = {
Accept: 'application/json',
...options.headers,
};
options.body = data;
}
}
}
// 支持类似axios 参数自动拼装, 其他method也可用, 不冲突.
if (options.params && Object.keys(options.params).length > 0) {
const str = url.indexOf('?') !== -1 ? '&' : '?';
url = `${
url}${
str}${
stringify(options.params)}`;
}
return {
url,
options,
};
};
fetch.js
主要是定义了request和response拦截器。
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进