小程序开发中,很多地方都要请求后台接口,如果所有的接口请求都调用小程序官方文档给的网络请求方法wx.request({ }),千篇一律的重复代码显得太过于臃肿,繁琐,作为一个对代码艺术美有崇高追求的广大开发者朋友,肯定是不愿意看到的,那么封装一个高效稳定优雅的网络请求统一接口就显得尤为重要,笔者结合众多项目实战经验整理后,把封装好的代码分享给广大开发者,大家拿去就可以直接用。截止目前,随着笔者的不断完善,本篇要分享的小程序网络请求公共接口已在很多个小程序项目中验证过了,很稳定,近乎完美,从来没有出现过异常情况,下面直接看代码。
在app.js中移入下面代码,在其他页面相关的js中引入app,就可以直接传参调用这个方法了
const apiHost = "http://192.168.0.110:8081/app/" //此处的IP域名信息填写自己本地或线上环境IP或域名信息
var mCurrentRequestNums = null
const LOGIN = 10000
const CHECKTOKEN = 10001
var mCurrentRequestNums = null
var token = null;
var member = null;
App({
requestCount:[],
onLaunch:function(){
token = wx.getStorageSync("token");
var logs = wx.getStorageSync("logs") || [];
logs.unshift(Date.now());
wx.setStorageSync("logs",logs );
wx.login({
success:function(res){
//发送res.code到后台换取openid,sessionKey,unionId
}
})
},
toLogin: function () {
var that = this;
wx.checkSession({
success: function () {
//session_key 未过期,并且在本生命周期一直有效
var temp = wx.getStorageSync("token");
if (temp == null || temp == "") {
that.login();
} else {
var res = { token: temp }
that.webCall("wxlogin/checkToken", res, CHECKTOKEN, that.onSuccess, that.onErrorBefore, that.onComplete, false, "GET");
}
},
fail: function () {
// session_key 已经失效,需要重新执行登录流程//重新登录
that.login();
}
})
},
login: function () {
var that = this;
wx.login({
success: res => {
that.webCall("wxlogin/login",res, LOGIN, that.onSuccess, that.onErrorBefore, that.onComplete, false, "GET");
}
})
},
onComplete: function (resultCode){
if (--mCurrentRequestNums <= 0) {
wx.hideNavigationBarLoading();
}
},
onSuccess: function (data, requestCode) {
var that = this;
switch (requestCode) {
case LOGIN:
token = data.data.token;
member = data.data;
wx.setStorageSync("token", token);
wx.setStorageSync("member", member);
console.log(token);
break;
case CHECKTOKEN:
if (data.code != '000') {
//token过期
that.login();
} else {
member = data.data;
wx.setStorageSync("member", member);
}
break;
}
},
/**
* 小程序请求后台接口 网络请求统一接口
* @param {Object} urlPath 接口访问路径
* @param {Object} params 访问参数(json格式)
* @param {Object} requestCode 访问码,返回处理使用
* @param {Object} onSuccess 成功回调
* @param {Object} onErrorBefore 失败回调
* @param {Object} onComplete 请求完成(不管成功或失败)回调
* @param {Object} isVerify 是否验证重复提交
* @param {Object} requestType 请求类型(默认POST)
* @param {Object} retry 访问失败重新请求次数(默认1次)
*/
webCall: function (urlPath, params, requestCode, onSuccess, onErrorBefore, onComplete, isVerify, requestType, retry) {
var params = arguments[1] ? arguments[1] : {};
var onSuccess = arguments[3] ? arguments[3] : function () { };
var onErrorBefore = arguments[4] ? arguments[4] : this.onError;
var onComplete = arguments[5] ? arguments[5] : this.onComplete;
var isVerify = arguments[6] ? arguments[6] : false;
var requestType = arguments[7] ? arguments[7] : "POST";
var retry = arguments[8] ? arguments[8] : 1;
var that = this;
//防止重复提交,相同请求间隔时间不能小于500毫秒
var nowTime = new Date().getTime();
if (this.requestCount[urlPath] && (nowTime - this.requestCount[urlPath]) < 500) {
return;
}
this.requestCount[urlPath] = nowTime;
//是否验证重复提交
if (isVerify) {
if (this.verifyCount[urlPath]) {
return;
}
this.verifyCount[urlPath] = true; //重复验证开关开启
}
urlPath = apiHost + urlPath;
params.token = token;
console.log("发起网络请求, 路径:" + (urlPath) + ", 参数:" + JSON.stringify(params));
wx.request({
url: urlPath,
data: params,
method: requestType, // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: {
'content-type': 'application/json;charset=utf-8',
"Content-Encoding": "gzip"}, // 设置请求的 header
success: function (res) {
console.log("返回结果:" + JSON.stringify(res.data));
if (res.data) {
if (res.statusCode == 200) { //访问成功
onSuccess(res.data, requestCode);
} else {
onErrorBefore(0, res.data.message == null ? "请求失败 , 请重试" : res.data.message, requestCode);
}
} else {
onErrorBefore(0, "请求失败 , 请重试", requestCode);
}
},
fail: function (res) {
retry--;
console.log("网络访问失败:" + JSON.stringify(res));
if (retry > 0) return that.webCall(urlPath, params, requestCode, onSuccess, onErrorBefore, onComplete, requestType, retry);
},
complete: function (res) {
onComplete(requestCode);
//请求完成后,2秒后重复验证的开关关闭
if (isVerify) {
setTimeout(function () {
that.verifyCount[urlPath] = false;
}, 2000);
}
}
})
}
})
在其他页面的js中调用本接口示例如下
const app = getApp() //获取应用实例
const GET_FIRST_PAGE = 1009 //requestCode
var mCurrentRequestNums = null
Page({
data:{},
getHotActivityByCity: function (param) {//根据选择的城市查询热门活动
wx.showNavigationBarLoading();
//调用前面封装好的网络请求统一接口
app.webCall("appseller/getHotActivityByCity", param, GET_FIRST_PAGE, this.onSuccess, this.onErrorBefore, this.onComplete, false, "GET");
},
/**
* 接口访问成功
* @param {Object} resultCode
*/
onSuccess: function (data, requestCode) {
this.setData({ adList: data });
},
/**
* 接口访问完成
* @param {Object} resultCode
*/
onComplete: function (resultCode) {
console.log("has completed");
if (--mCurrentRequestNums <= 0) {
wx.hideNavigationBarLoading();
}
},
})
欢迎广大开发者一起交流学习,笔者电话微信18629374628