English | 简体中文
网络请求库,基于 fetch 封装, 兼具 fetch 与 axios 的特点, 旨在为开发者提供一个统一的api调用方式, 简化使用, 并提供诸如缓存, 超时, 字符编码处理, 错误处理等常用功能.
- url 参数自动序列化
- post 数据提交方式简化
- response 返回处理简化
- api 超时支持
- api 请求缓存支持
- 支持处理 gbk
- 类 axios 的 request 和 response 拦截器(interceptors)支持
- 统一的错误处理方式
| 特性 | umi-request | fetch | axios |
|---|---|---|---|
| 实现 | 浏览器原生支持 | 浏览器原生支持 | XMLHttpRequest |
| 大小 | 9k | 4k (polyfill) | 14k |
| query 简化 | ✅ | ❎ | ✅ |
| post 简化 | ✅ | ❎ | ❎ |
| 超时 | ✅ | ❎ | ✅ |
| 缓存 | ✅ | ❎ | ❎ |
| 错误检查 | ✅ | ❎ | ❎ |
| 错误处理 | ✅ | ❎ | ✅ |
| 拦截器 | ✅ | ❎ | ✅ |
| 前缀 | ✅ | ❎ | ❎ |
| 后缀 | ✅ | ❎ | ❎ |
| 处理 gbk | ✅ | ❎ | ❎ |
| 快速支持 | ✅ | ❓ | ❓ |
更多讨论参考传统 Ajax 已死,Fetch 永生, 如果你有好的建议和需求, 请提 issue
- rpc支持
- 测试用例覆盖85%+
- 写文档
- CI集成
- 发布配置
- typescript
npm install umi-request --save
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| method | 请求方式 | string | get , post , put ... | get |
| params | url请求参数 | object | -- | -- |
| charset | 字符集 | string | utf8 , gbk | utf8 |
| requestType | post请求时数据类型 | string | json , form | json |
| data | 提交的数据 | any | -- | -- |
| responseType | 如何解析返回的数据 | string | json , text , blob , formData ... | json , text |
| getResponse | 是否获取源response, 返回结果将包裹一层 | boolean | -- | fasle |
| timeout | 超时时长, 默认毫秒, 写操作慎用 | number | -- | -- |
| useCache | 是否使用缓存 | boolean | -- | false |
| ttl | 缓存时长, 0 为不过期 | number | -- | 60000 |
| prefix | 前缀, 一般用于覆盖统一设置的prefix | string | -- | -- |
| suffix | 后缀, 比如某些场景 api 需要统一加 .json | string | -- | -- |
| errorHandler | 异常处理, 或者覆盖统一的异常处理 | function(error) | -- | |
| headers | fetch 原有参数 | object | -- | {} |
| credentials | fetch 请求包含 cookies 信息 | object | -- | credentials: 'include' |
fetch原其他参数有效, 详见fetch文档
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| maxCache | 最大缓存数 | number | 不限 |
| prefix | 默认url前缀 | string | -- |
| errorHandler | 默认异常处理 | function(error) | -- |
| headers | 默认headers | object | {} |
| params | 默认带上的query参数 | object | {} |
| ... |
request 可以进行一层简单封装后再使用, 可参考 antd-pro
// request 是默认实例可直接使用, extend为可配置方法, 传入一系列默认参数, 返回一个新的request实例, 用法与request一致.
import { extend } from 'umi-request';
const request = extend({
maxCache: 10, // 最大缓存个数, 超出后会自动清掉按时间最开始的一个.
prefix: '/api/v1', // prefix
suffix: '.json', // suffix
errorHandler: (error) => {
// 集中处理错误
},
headers: {
some: 'header' // 统一的headers
},
params: {
hello: 'world' // 每个请求都要带上的query参数
}
});
request('/some/api');
// 支持语法糖 如: request.get request.post ...
request.post('/api/v1/some/api', { data: {foo: 'bar'}});
// 请求一个api, 没有method参数默认为get
request('/api/v1/some/api').then(res => {
console.log(res);
}).catch(err => {
console.log(err);
});
// url参数序列化
request('/api/v1/some/api', { params: {foo: 'bar'} });
// post 数据提交简化
// 当data为object时, 默认requestType: 'json'可不写, header会自动带上 application/json
request('/api/v1/some/api', { method:'post', data: {foo: 'bar'} });
// requestType: 'form', header会自动带上 application/x-www-form-urlencoded
request('/api/v1/some/api', { method:'post', requestType: 'form', data: {foo: 'bar'} });
// reponseType: 'blob', 如何处理返回的数据, 默认情况下 text 和 json 都不用加. 如blob 或 formData 之类需要加
request('/api/v1/some/api', { reponseType: 'blob' });
// 提交其他数据, 如文本, 上传文件等, requestType不填, 手动添加对应header.
request('/api/v1/some/api', { method:'post', data: 'some data', headers: { 'Content-Type': 'multipart/form-data'} });
// 默认返回的就是数据体, 如果需要源response来扩展, 可用getResponse参数. 返回结果会多套一层
request('/api/v1/some/api', { getResponse: true }).then({data, response} => {
console.log(data, response);
});
// 超时 单位毫秒, 但是超时后客户端虽然返回超时, 但api请求不会断开, 写操作慎用.
request('/api/v1/some/api', { timeout: 3000 });
// 使用缓存, 只有get时有效. 单位毫秒, 不加ttl默认60s, ttl=0不过期. cache key为url+params组合
request('/api/v1/some/api', { params: { hello: 'world' }, useCache: true, ttl: 10000 });
// 当服务端返回的是gbk时可用这个参数, 避免得到乱码
request('/api/v1/some/api', { charset: 'gbk' });
// request拦截器, 改变url 或 options.
request.interceptors.request.use((url, options) => {
return (
{
url: `${url}&interceptors=yes`,
options: { ...options, interceptors: true },
}
);
});
// response拦截器, 处理response
request.interceptors.response.use((response, options) => {
response.headers.append('interceptors', 'yes yo');
return response;
});import request, { extend } from 'umi-request';
/**
* 这里介绍四种处理方式
*/
/**
* 1. 统一处理
* 常用于错误码较规范的项目中, 集中处理错误.
*/
const codeMap = {
'021': '发生错误啦',
'022': '发生大大大大错误啦',
...
};
const errorHandler = (error) => {
const { response, data } = error;
message.error(codeMap[data.errorCode]);
throw error; // 如果throw. 错误将继续抛出.
// return {some: 'data'}; 如果return, 将值作为返回. 不写则相当于return undefined, 在处理结果时判断response是否有值即可.
}
const extendRequest = extend({
prefix: server.url,
errorHandler
});
const response = await extendRequest('/some/api'); // 将自动处理错误, 不用catch. 如果throw了需要catch.
if (response) {
// do something
}
/**
* 2. 单独特殊处理
* 如果配置了统一处理, 但某个api需要特殊处理. 则在请求时, 将errorHandler作为参数传入.
*/
const response = await extendRequest('/some/api', {
method: 'get',
errorHandler: (error) => {
// do something
}
});
/**
* 3. 不配置 errorHandler, 将reponse直接当promise处理, 自己catch.
*/
try {
const response = await request('/some/api');
} catch (error) {
// do something
}
/**
* 4. 基于response interceptors
*/
request.interceptors.response.use((response) => {
const codeMaps = {
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
message.error(codeMaps[response.status]);
return response;
});
/**
* 5. 对于状态码实际是 200 的错误
*/
request.interceptors.response.use(async (response) => {
const data = await response.clone().json();
if(data && data.NOT_LOGIN) {
location.href = '登录url';
}
return response;
})- npm install
- npm run dev
- npm link
- 然后到你测试的项目中执行 npm link umi-request
- 引入并使用
- @clock157
- @yesmeck
- @yutingzhao1991