在小程序中请求接口的唯一方式是调用wx.request接口,该api被调用后把请求数据交由微信客户端转发去请求服务器端接口;除了此接口没有其他能够实现请求接口的方式方法。
wx.request接口使用起来不太方便。接口调用失败的时候可以不可以全局统一处理并给出提示?接口成功的时候能不能对接口返回的结果做统一处理?接口调用时能不能在console控制台打印日志来方便查看接口相关信息,比如请求地址、请求方式、请求头、请求参数(体)、响应体等等?要实现这些功能就得自己封装了!所以为了实现以上的需求自己封装了一个简单的http请求工具。
工具实现的主要功能:
1、请求自动注入token
2、console控制台打印请求日志,便于开发联调、测试判断bug归属
3、封装默认请求参数与请求方法简化接口调用书写复杂度,实现类axios方式调用
4、Promise化wx.request接口
5、全局统一处理接口返回结果
6、全局统一加载动画
详细代码与示例如下。
const dateTool = require('/DateUtil.js')
// 请求方式
const httpMethod = {
get: 'GET',
post: 'POST'
}
// 默认配置
const defaultConfig = {
header: {
'contentType': 'application/json', // 默认json,可以修改
'getAuthorization': () => wx.getStorageSync('token').AuthorityToken == undefined ? '' : wx.getStorageSync('token').AuthorityToken,
},
dataType: 'json', // 返回的数据格式,默认json,可修改
responseType: 'text', // 响应的数据类型,默认text,可修改
loading: true, // 是否显示loading动画
delay: 1000, // loading动画延迟显示的时间,单位:毫秒(ms)
}
function httpLogInfo(url, params, res, method, header) {
console.log('当前时间:' + dateTool.sampleFormatTime(new Date(Date.now())) + '\n当前url:' + url);
console.log('头部:', header);
console.log('方式:', method);
console.log('参数:', params);
console.log('结果:', res.data);
}
function httpLogErr(url, params, res, method, header) {
console.log('请求发生异常,当前时间:' + dateTool.sampleFormatTime(new Date(Date.now())) + '\n当前url:' + url);
console.log('头部:', header);
console.log('方式:', method);
console.log('参数:', params);
console.log('异常:', res);
}
function successCallback(res, url, params, resolve, reject, method, header) {
httpLogInfo(url, params, res, method, header);
if (res.statusCode === 200 && res.data.Code != -10003) {
if (res.data.Code === 1) { // 成功,Code判断的值根据实际api返回进行修改
return resolve(res.data.Data)
}
if (res.data.Code === 0) { // 失败
wx.showToast({
title: res.data.Message,
icon: 'none'
})
return reject(res.data.Data)
}
} else {
wx.showToast({
title: '加载数据失败了,请重试',
icon: 'none'
})
return reject(res.data.Data)
}
}
function failCallback(res, url, params, resolve, reject, method, header) {
httpLogErr(url, params, res, header);
if (res.errMsg.includes('request:fail')) {
wx.showToast({
title: '网络无法连接服务器,请稍后再试',
icon: 'none'
});
}
return reject(res)
}
const httpRequest = (url, {
data = {},
method = httpMethod.get,
dataType = defaultConfig.dataType,
responseType = defaultConfig.responseType,
header = {},
loading = defaultConfig.loading,
delay = defaultConfig.delay
} = {}) => {
const headers = Object.assign({
// header采用拼接是为了防止本地存储的loginInfo被其他地方修改了而不能得到最新
'content-type': defaultConfig.header.contentType,
'Authorization': defaultConfig.header.getAuthorization()
}, header)
/** 秒级响应不再显示loading弹窗 */
let timeoutId = setTimeout(() => {
if (loading) {
timeoutId = 0
wx.showLoading({
title: '加载中',
mask: true
})
}
}, delay)
const promise = new Promise((resolve, reject) => {
wx.request({
url: url,
data: data,
method: method,
header: headers,
dataType: dataType,
responseType: responseType,
success(res) {
loading = false
// timeoutId为0时说明已经执行了wx.showLoading
// 则此时需要调用wx.hideLoading
// wx.showToast与wx.showLoading只能存在一个,故fail中不再调用wx.hideLoading
if (timeoutId === 0) {
wx.hideLoading()
}
successCallback(res, url, data, resolve, reject, method, header);
},
fail(res) {
failCallback(res, url, data, resolve, reject, method, header);
}
})
})
return promise
}
// 扩展请求方式
Object.keys(httpMethod).forEach(method => {
httpRequest[method] = (url, params = {}, config = {}) => {
return httpRequest(url, {
data: params,
method: httpMethod[method],
...config
})
}
})
module.exports = httpRequest
注:DateUtil.js为日期格式化工具
这是对wx.request的简单封装,不完整,不完善的地方欢迎大家补充与改进。
2020年4月16日09:38:44