浅谈小程序中的请求封装
浅谈小程序中的请求封装
近两个月学习了小程序的开发,并且撸了一个不大不小的demo,算是正式入门了小程序,在此想分享下小程序的开发经验。
前言
在小程序的开发中,或者说在整个前端开发中,请求都是绕不过去的一道坎。在vue开发中,我们可以采用 这个成熟的插件来进行http请求。但是,遗憾的是,到目前为止,小程序没有一个比较好用的插件来进行http请求。此时,我们需要对小程序的http请求进行封装,以方便我们后续开发。
浅析wx.request
众所周知,在小程序中,我们通过 wx.request
方法来进行http请求(或者说是https请求)。
通过 我们可以知道, wx.request
方法接收一个对象,对象可以有9个属性:url
,data
,header
,method
,datatype
,responsetype
,success
,fail
,complete
。除了url
是必填的以外,其余都是可选项。在这些属性里面,最常用的是 method
,data
,header
,success
以及fail
这几个属性。毕竟我们总要设置请求方法、请求数据、请求头以及请求成功或失败的处理方法是不是?
所以接下来我们的目标我们已经明确,就是对这些常用属性进行封装。
封装http类
对于http请求的封装,有很多种方法,比如:axios 采用的是通过iife作为工厂函数处理并返回一个axios的实例。在这里,我推荐使用类,因为类的封装形式,正是axios 的封装形式的加强版。
为了一致性,我也采用request作为请求的方法名,并且接受相同的对象作为参数。此时,我们已经可以实现出以下代码:
class http { request (params) { wx.request({ url: params.url, method: params.method, data: params.data, header: params.header, success: (res) => { params.success(res) }, fail: (err) => { params.fail(err) } }) } }
接下来,我们需要对各个属性进行处理。
缺省属性处理
由于除了url
,其余的的属性皆为可选可选项,所以需要对可选属性进行缺省属性的处理。
在小程序官方文档中,当不传入method
属性时,默认采用get
方法,所以我们需要将method的默认值设为get
,设置method的默认值的方式很简单:
if (!params.method) { params.method = 'get' }
但是,这种方式不够优雅,我们可以采用位运算符的方式进行默认复制:
... method: params.method || 'get' ...
其余属性也采用类似方式进行缺省值处理,除了success
和fail
属性,这个我们后面说。
从配置文件中导入http参数
在正常情况下,rest风格的接口协议给的接口路径都是诸如/patha/a
,在此之前还有一个类似于www.baidu.com/root
类似的base url,两者结合才是真正的请求路径。在vue中,我们可以通过webpack中的proxytable来解决这个问题,但是,小程序中没有webpack中的proxytable,所以需要每次请求的时候,都输入完整请求路径。
在http类中的request
方法,我们可以实现路径的拼接。
... url: 'www.baidu.com/root' + params.url, ...
但是,这里有个问题,base url是写死的,也就是说,我们每做一个项目,都需要重新设置一次base url的值,这显然是有问题的。
为了处理该问题,我新建了一个config.js文件,作为该项目的配置文件,用来存储所有项目相关的配置,比如base url以及http header。
const config = { api_base_url: 'www.baidu.com/root', // 更多的配置项 } export {config}
拥有配置文件最大的好处就是,每次修改项目,只需要修改配置文件中的配置项的值即可,重复保证了组件的封闭性,减少了对项目的耦合。
封装success
最后,我们需要封装success
以及fail
。
显而易见,我们只有在http状态码为2**
或者304
才调用success,所以我们需要对响应结果的状态码进行判断,根据判断结果决定是否执行params.success
... success: (res) => { let code = res.statuscode.tostring() // 状态码判断 if (code.startswith('2') || code === '304') { params.success && params.success(res.data) } else { // 失败 } }
tips:一般情况下,我们还可以对显示错误的方法进行一次封装,调用wx.showtoast
显示服务器返回的错误信息。
全部代码
经过这么多步骤,封装结束后的代码是:
import {config} from '../config.js' class http { request (params) { wx.request({ url: config.api_base_url + params.url, method: params.method || 'get', data: params.data || {}, header: params.header ? object.asign(config.header, params.header):config.header success: (res) => { let code = res.statuscode.tostring() if (code.startswith('2') || code === '304') { params.success && params.success(res.data) } else { params.fail && params.fail(res.data) let error_code = res.data.error_code this._show_error(error_code) } }, fail: (err) => { params.fail && params.fail(res.data) this._show_error(1) } }) } // 私有方法,显示请求错误信息 _show_error(error_code) { if (!error_code) { error_code = 1 } const tip = config.tips[error_code] wx.showtoast({ title: tip ? tip : tips[1], icon: 'none', duration: 2000 }) } }
其实,http类还可以进一步优化,比如,使用解构以及默认赋值,使用promise等等,篇幅有限,我就不一一细说了,详情可以查看我github上的代码。
代码路径:https://github.com/karthuslorin/mini-program/blob/master/util/http.js
如果觉得不错,github点个star再走呗?