@sunmi/request
v1.0.6
Published
wrapped fetch method
Downloads
6
Readme
简介
基于fetch的使用封装,借鉴Axios的api,用于网络请求
支持 browser端 和 node端 使用
安装
通过npm:
npm i @sunmi/request
浏览器引用:
<!-- 不支持fetch的浏览器需要polyfill -->
<!-- <script src="/path/to/whatwg-fetch.js" /> -->
<script src="/path/to/@sunmi/request/dist/index.js" />
<!-- 通过全局对象 request 使用 -->
API
基本使用
- request(config)
- request(url[, config])
创建实例
- request.create(config)
快捷方法
- request.get(url[, params[, config]])
- request.head(url[, params[, config]])
- request.delete(url[, params[, config]])
- request.post(url[, data[, config]])
- request.put(url[, data[, config]])
- request.patch(url[, data[, config]])
可访问属性
- request.defaults
- request.interceptors
配置
{
// 请求服务器url
url?: string;
// 自动加载 url 前面,除非 url 是绝对地址
baseURL?: string;
// 通过url传递的参数
params?: object | null;
// 将params序列化的函数
paramsSerializer?: (params: object) => string;
// 请求体数据,最终用于body字段的值,仅body未传值时生效,仅用于 POST、PUT、PATCH
data?: object | null;
// 请求体数据转换为body支持的类型(默认转换为URLSearchParams),与参数data配合使用,仅用于 POST、PUT、PATCH
transformData?: (data: object) => BodyInit;
// 在发送之前,修改请求体数据的钩子,仅用于 POST、PUT、PATCH
beforeRequest?: Array<(body: BodyInit) => BodyInit>;
// 在请求返回,传递给 then/catch 前,修改响应数据的钩子
afterResponse?: Array<(res: Response) => Response>;
// [未实现] 请求超时的毫秒数(0表示无超时),如果超时将reject一个Error({ type: 'RequestTimeout' })
timeout?: number;
// 响应数据类型,默认为json,并对象化处理, 取值 json、text、blob、arraybuffer、''
responseType?: XMLHttpRequestResponseType;
/** 以下是 fetch 原生支持的参数 **/
// 参考:https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch
method?: string;
headers?: HeadersInit;
body?: BodyInit | null;
mode?: RequestMode;
credentials?: RequestCredentials;
cache?: RequestCache;
redirect?: RequestRedirect;
referrer?: string;
referrerPolicy?: ReferrerPolicy;
integrity?: string;
}
使用示例
直接使用 fetch 发送请求,响应数据为json格式字符串,如下
// (1) GET
const params = {
key: 'key',
name: 'name'
};
const queryString = qs.stringify(params, { arrayFormat: "brackets" });
fetch(`http://domain.com/webapi/some/action?${queryString}`, {
method: 'GET'
})
.then(res=>res.json())
.then(res=>{})
.catch(e=>{})
// (2) POST
const data = {
key: 'key',
name: 'name'
};
const formdata = new URLSearchParams();
Object.keys(data).map(key=>{
formdata.append(key, data[key])
})
fetch(`http://domain.com/webapi/some/action`, {
method: 'POST',
body: formdata
})
.then(res=>res.json())
.then(res=>{})
.catch(e=>{})
使用 request 来实现上述fetch操作
// (1) GET
request.get(
'http://domain.com/webapi/some/action', {
key: 'key',
name: 'name'
})
.then(res=>{})
.catch(e=>{})
// (2) POST
request.post('http://domain.com/webapi/some/action', {
key: 'key',
name: 'name'
})
.then(res=>{})
.catch(e=>{})
request.create
request可直接使用发起请求,也可以通过create
方法,创建使用指定配置的实例,实例将拥有 request 的所有方法。
通常使用 create 方法来创建使用不同配置的实例,避免每次请求是重复传递配置参数
配置生效顺序:默认配置 < create创建实例的配置 < 请求方法传入的配置
const rq = request.create({
baseURL: 'http://domain.com'
})
// 发起上述 (1)的GET 请求
rq.get('/webapi/some/action', {
key: 'key',
name: 'name'
})
.then(res=>{})
.catch(e=>{})
// 发起上述 (2)的POSTT 请求
rq.post('/webapi/some/action', {
key: 'key',
name: 'name'
})
.then(res=>{})
.catch(e=>{})
request.get
request.get(url[, params[, config]])
get 请求的快捷方法。与之相关的配置参数有 params
、paramsSerializer
。
import qs from 'qs';
const rq = request.create({
baseURL: 'http://domain.com',
paramsSerializer: function(params) {
return qs.stringify(params, { arrayFormat: 'brackets' })
}
});
rq.get(
'/webapi/some/action',
{ key: 'key', name: 'name' }
)
.then(res=>{})
.catch(e=>{})
// 等同于
request.get('/webapi/some/action', null, {
baseURL: 'http://domain.com',
params: { key: 'key', name: 'name' }
})
配置参数 paramsSerializer
的默认值,是对 qs.stringify(params, { arrayFormat: 'brackets' })
的实现
request.head
request.head(url[, params[, config]])
使用参数同 request.get
request.delete
request.delete(url[, params[, config]])
使用参数同 request.get
request.post
request.post(url[, data[, config]])
post 请求的快捷方法。与之相关的配置参数有 data
、transformData
、beforeRequest
, body
。
/**
* 1. 发送URLSearchParams数据
*/
request.post('http://domain.com/webapi/some/action', {
key: 'key',
name: 'name'
})
.then(res=>{})
.catch(e=>{})
/**
* 2. 如果需要发送formdata格式数据
*/
const rq = request.create({
baseURL: 'http://domain.com',
transfromData: function(data){
const formdata = new FormData();
Object.keys(data).map(key=>{
formdata.append(key, data[key])
})
// 这里甚至可以添加额外的数据,比如给每个请求添加身份token
return formdata
}
})
rq.post('/webapi/some/action', {
key: 'key',
name: 'name'
})
.then(res=>{})
.catch(e=>{})
/**
* 3. 如果发送请求前需要对body做一些处理,执行顺序在tansformData之后
*/
request.post('http://domain.com/webapi/some/action', {
key: 'key',
name: 'name'
}, {
// 由于data默认转换类型为URLSearchParams,假设服务端现在需要FormData格式
beforeRequest: [
function(body) {
const formdata = new FormData()
body.keys().map(key=>{
formdata.append(key, body.get(key))
})
return formdata
}
]
})
.then(res=>{})
.catch(e=>{})
/**
* 4. data和transformData用于生成body,如果配置参数传递了body,则直接以body作为请求体
*/
const formdata = new FormData();
formdata.append('key', 'key2')
request.post('http://domain.com/webapi/some/action', {
key: 'key',
name: 'name'
}, {
body: formdata
})
.then(res=>{})
.catch(e=>{})
// 最终发往服务器的数据是 { key: 'key2' }
配置参数 transform
的默认值,是一个将 data
对象 转化为 URLSearchParams
类型的函数
request.put
request.put(url[, params[, config]])
使用参数同 request.post
request.patch
request.patch(url[, params[, config]])
使用参数同 request.post
拦截器
在请求或响应被 then 或 catch 处理前拦截它们,处理后返回一个promise
// 添加请求拦截器
request.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
request.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
如果希望在使用后移除拦截器
const myInterceptor = request.interceptors.request.use(function () {/*...*/});
request.interceptors.request.eject(myInterceptor);
使用create创建的request实例,也可以添加拦截器
const rq = request.create(config)
rq.interceptors.request.use(function(){/**/})
对于fetch,仅当遇到网络错误时,才会reject,HTTP 404 状态并不被认为是网络错误;而对于实际业务场景可能会有如下情况
- 除了HTTP 200其余一概视为错误
- 给每个请求的头部统一加上身份authorization
- 根据response中的某些字段来判断结果是否正确
- ...
此时就可以使用拦截器来完成这一处理
/**
* 给请求头添加authorization
*/
request.interceptors.request.use(function(config) {
const headers = new Headers();
headers.append('authorization', 'sssssss')
config.headers = headers
return config
}, function(err){
return Promise.reject(err);
})
/**
* 如响应结果
* 成功:{ code: 200, data: { ... }, msg: '' }
* 失败:{ code: 400, data: null, msg: 'error' }
*/
request.interceptors.response.use(function(response) {
if(response.code === 200) {
return response
} else {
return Promise.reject(response);
}
}, function() {
return Promise.reject(err);
})