二次封装http请求对象

196 阅读3分钟

这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。

功能设计

axios是目前非常流行的http请求库,但是不管是B端,还是C端的新项目。我们都有一个很大的问题就是每次用起来就要去百度,google,bying搜索如何从0还是配置,于是我们就想二次封装axios,省去很多繁杂的业务流程,我梳理了如下业务痛点,根据目前的痛点做了一部分梳理

  • 重复请求缓存(两种情况)
  • 错误异常是否 抛出 或者 return
  • 全局异常捕捉控制
  • 超时时间设置,请求超时的重发
  • 支持取消请求 (这里要兼顾多种场景)
  • 考虑JSONP
  • 支持自定义拦截器
  • 全局配置
  • debug模式(耗时)
  • 自定义answer通用对象
  • 提供自定义代理(mock server)
  • 多种环境考虑设计

使用方式

1.  `import {create} from 'http';`
1.  ``
1.  `const http = create({`
1.  `baseUrl:'http://baidu.com/'`
1.  ``
1.  `Headers:{`
1.  `'ua':'ios',`
1.  `}`
1.  ``
1.  `isProd:true,//是否所有切为正式接口`
1.  ``
1.  `timeout:5000,`
1.  ``
1.  `answer:true, // 是否启用 answer对象`
1.  ``
1.  `JSONP:false,//JSONP模式开启`
1.  ``
1.  `isTimeoutRefresh,//是否重发`
1.  ``
1.  `debug:true, // 调式是否开启`
1.  ``
1.  `// 如何判断响应为成功`
1.  `answerInterceptor:(answer){`
1.  `// 根据后端业务状态码表`
1.  `if(answer.get('code') == 200000){`
1.  `answer.setOk(true);`
1.  `}`
1.  `return answer;`
1.  `}`
1.  ``
1.  `});`
1.  ``
1.  `const an = await http.get('column/column-info/v2.0',{columnId:26219422});`

全局环境切换

提供全局的环境切换,我们预配置环境config,通过预配置的环境进行逻辑开发,提供一个switch的切换方法,方便全测,正式,mock等环境进行切换。不需要每次手动更改baseURL的逻辑

1.  `// 需要预先配置 config`
1.  `local:{`
1.  `proxy:'localhost://testapi'`
1.  `},`
1.  ``
1.  `dev:{`
1.  `proxy:'http://123.12.3.0'`
1.  `}`
1.  ``
1.  `prod:{`
1.  `proxy:'http://baidu.com`
1.  `}`
1.  ``
1.  `http.switchToEnv('envB'); //切换环境为 evnB`

统一的事件处理系统

使用完整的事件系统的好处是什么呢,首选我们能够监听一个完整的http请求和响应的过程,在此过程中我们做了事件机制,在request,response,error三个事件中可以更加清楚的处理个各自的逻辑,直接将解耦了内容,我们不需要再去axios的请求拦截器,响应拦截器去处理逻辑,首先是晦涩难懂,二是逻辑严重耦合。采用事件机制我们的功能模块处理更好的抽离出来。

# 事件系统

-   开始请求

    ```
    http.on('request',request=>{  request.url = 'https:' +request.url ;  return request})
    ```

-   响应

    ```
    http.on('response',response=>{  return response;})
    ```

-   统一全局错误捕获

    ```
    http.on('error',err=>{  // 错误处理  console.log(err)})
    ```

通用应答对象

为什么要做通用应答对象,这是业务中痛点最明显的,可以发现我们状态码很多都是一个固定的成功码,失败码,然后我们要判断成功,判断失败进行重复的逻辑判断,这时候既然是二次封装,那我们就将它抽离出来,然后抽离出来进行生成一个统一的应答对象。这个对象只需要判断isOk即可,完全不需要判断内部状态时变动还是迁移,解决了前后端联调的问题。

1.  `const an = await miguHttp.get('column/column-info/v2.0',{columnId:26219422});`
1.  `// 成功`
1.  `if(an.ok){`
1.  `answer.get('code')`
1.  `}`