1.0.6 • Published 2 years ago

@sunmi/request v1.0.6

Weekly downloads
8
License
ISC
Repository
-
Last release
2 years ago

简介

基于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.create(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 请求的快捷方法。与之相关的配置参数有 paramsparamsSerializer

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 请求的快捷方法。与之相关的配置参数有 datatransformDatabeforeRequest, 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);
})
1.0.6-beta.1

2 years ago

1.0.6-beta.0

2 years ago

1.0.6

2 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.3-beta.0

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.1-beta.1

5 years ago

1.0.1-beta.0

5 years ago