浅谈小程序中的请求封装
浅谈小程序中的请求封装
近两个月学习了小程序的开发,并且撸了一个不大不小的demo,算是正式入门了小程序,在此想分享下小程序的开发经验。
前言
在小程序的开发中,或者说在整个前端开发中,请求都是绕不过去的一道坎。在Vue开发中,我们可以采用 axios 这个成熟的插件来进行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再走呗?