写这篇文章,主要是因为前阵子(其实就是一两周前)被大佬要求画出授权时序图,然后我不出意外被教训了一顿,哈哈,经过一顿梳理,整出了下图:
上图为相应的时序图(字丑,能看懂就好别介意哈!)
为什么这图会有sessionId呢?因为小程序的请求wx.login返回的code是会过期的。根据是否过期去判断是否需要重新登录小程序。sessionId怎么来的呢?是根据小程序getAccessToken返回的7200秒去定义的,sessionId肯定是要少于微信定义的秒数,这样才能确保有效性。生成了sessionId传给前端之后,前端需要将sessionId保存在缓存中。在登录超时时,后台需要返回一个状态给前端判断当前的sessionId是否过期,如过期则进行二次请求。
上面一段话是说为什么有二次登录的,下面是授权的,由于小程序的改版,小程序的授权只能是跳到相应的页面点击授权(至少我现在只有这个方法,之前弹框后叫进行授权的,写是openSetting这个版本已经不行了)。如果请求接口需要授权的话,需要跳入授权函数。
如果请求时间过长怎么办呢?是不是需要再次请求?如果在fail中一直请求进入了死循环。这个不可行,怎么办呢?设置请求时间,在fail的时候进行询问是否进行再次请求,如点击确定则进行请求,否则什么都不做。
我该说的都说了,下面上代码(这一大段代码放在util.js中的):
module.exports = {HttpRequst: HttpRequst
}
// const baseUrl = "https://hi.xxx.com/cxyTicket/";//测试环境
const baseUrl = "https://xxx.com/hospital/"; //正式环境//sessionChoose 1是GET方法 2是Post方法
//ask是是否要进行询问授权,true为要,false为不要
//sessionChoose为1,2,所以paramSession下标为0的则为空
function HttpRequst(loading, url, sessionChoose, params, method, ask, callBack) {params = Object.assign({}, { "thirdSession":wx.getStorageSync("sessionId")}, params);//由于这次的方法是sessionId当参数传入,所以不像第一次写的一样放于请求头if (loading == true) {wx.showToast({title: '数据加载中',icon: 'loading'})}let paramSession = [{},{'content-type': 'application/json' },{ 'content-type': 'application/x-www-form-urlencoded'}]wx.request({url: baseUrl + url,data: params,dataType: "json",header: paramSession[sessionChoose],method: method,success: function (res) {if (loading == true) {wx.hideToast(); //隐藏提示框}if (res.data.object.LoginOutTimeState) {//判断过期的话重新获取console.log(res.data.object.LoginOutTimeState);console.log("32243已经超时了进来了");wxLogin(loading, url, sessionChoose, params, method, ask, callBack);}if (wx.getStorageSync("sessionId")){if (res.data.object.InfoState ==0){getUserInfo(loading, url, sessionChoose, params, method, ask, callBack);//判断用户是否授权}}callBack(res.data);},fail:function(res){console.log(res);wx.showModal({title: '提示',content: '请求失败!由于网络请求时间过长或网络无法连接的原因,请确认网络畅通,点击"重新请求"进行再次请求!',confirmText: "重新请求",success: function (res) {if (res.confirm) {HttpRequst(loading, url, sessionChoose, params, method, ask, callBack);//再次进行请求} else if (res.cancel) {console.log('用户点击取消');}}})},complete: function () {if (loading == true) {wx.hideToast(); //隐藏提示框}}})
}function wxLogin(loading, url, sessionChoose, params, method, ask, callBack) {wx.login({success: function (res) {var code = res.code; //得到codeHttpRequst(true, "wx/SP/wxlogin.do", 2, {"code": code}, "GET", true, function (res) {// console.log(res);if (res.code == 0) {wx.setStorageSync('sessionId', res.object.thirdSession);console.log(res.object.thirdSession);params.thirdSession = res.object.thirdSession;if (res.object.InfoState == 0) {console.log("这里没有用户信息");console.log(res.encryptedData);console.log(res.iv);getUserInfo(loading, url, sessionChoose, params, method, ask, callBack);//判断用户是否授权} else {HttpRequst(loading, url, sessionChoose, params, method, ask, callBack);}}})}})
}// 判断用户是否授权
function getUserInfo(loading, url, sessionChoose, params, method, ask, callBack){wx.getUserInfo({success: function (res) {HttpRequst(true, "wx/SP/saveInfo.do", 2, {"encryptedData": res.encryptedData,"iv": res.iv,"thirdSession": wx.getStorageSync("sessionId")}, "POST", false, function (res) {console.log("请求成功");wx.setStorageSync('avatarUrl', res.object.avatarUrl);wx.setStorageSync('nickName', res.object.nickName);HttpRequst(loading, url, sessionChoose, params, method, ask, callBack);})},fail: function (res) {console.log("我还没有授权");wx.navigateTo({url: '../allow_detail/allow_detail'})}})
}
想设置请求10秒后超时,进入fail函数怎么做呢?找到app.json,在最大的对象下加networkTimeout(我还顺带写了给引入插件的捏,嘿嘿嘿,当然插件也要在小程序平台设置第三方先才有效):
{"pages": ["pages/index/index","pages/allow_detail/allow_detail","pages/logs/logs"],"window": {"backgroundTextStyle": "light","navigationBarBackgroundColor": "#05a9c5","navigationBarTitleText": "xxx","navigationBarTextStyle": "#fff"},"plugins": {"Crypto": {"version": "0.0.003","provider": "wxf25d506ff81e19fb"}},"networkTimeout":{"request":20000,"connectSocket":20000}
}
超时也搞定了,授权的话由于改版,所以需要新页面,本来我是想写链接让你们跳到之前的博客的,但是考虑到程序员都懒,我就写下面吧。
allow_detail.html如下:
<!--pages/allow_get_detail/allow_get_detail.wxml-->
<view class="container"><view class="userinfo"><button open-type="getUserInfo" bindgetuserinfo="getUserInfo">授权</button></view><view class="usermotto"><text class="user-motto">点击授权,在弹框内点击'允许'即可授权。授权完成后重新进入小程序即可正常使用。</text></view>
</view>
allow_detail.js如下:
// pages/allow_get_detail/allow_get_detail.js
//index.js
//获取应用实例
const app = getApp()
var util = require('../../utils/util.js')
Page({data: {},onLoad: function () {},getUserInfo: function (e) {// 在没有 open-type=getUserInfo 版本的兼容处理wx.getUserInfo({success: res => {util.HttpRequst(true, "wx/SP/saveInfo.do", 2, {"encryptedData": res.encryptedData,"iv": res.iv,"thirdSession": wx.getStorageSync("sessionId")}, "POST", false, function (res) {wx.setStorageSync('avatarUrl', res.object.avatarUrl);wx.setStorageSync('nickName', res.object.nickName);wx.navigateBack();wx.redirectTo({url: '../index/index'})})console.log("获取头像3")},fail: res => {console.log("调用失败")}})},
})
写完啦,我博客真的不常上,想写东西记录点什么才上来的。
注:小程序session_key怎么获取的,小程序官方文档有教怎么获取,怎么做,我只是建议大家设置的时间不要超7200秒而已。