写这篇文章,主要是因为前阵子(其实就是一两周前)被大佬要求画出授权时序图,然后我不出意外被教训了一顿,哈哈,经过一顿梳理,整出了下图:
上图为相应的时序图(字丑,能看懂就好别介意哈!)
为什么这图会有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; //得到code
HttpRequst(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秒而已。