在开发微信小程序时,会先调用wx.login 获取 code 以后 调用 wx.getUserProfile() 获取rawData、signature、encryptedData、iv等信息,到后台进行处理;
但是随着4月28日24时后发布的新版本小程序,接口调整,这样写就会报错:error msg: ''getUserProfile:fail can only be invoked by user TAP gesture"。
文档说明:
常见问题
开始聊之前说一下我个人遇到过的偶发性不能解密encryptedData,导致提示签名失败
1、把wx.login() 放在了 wx.getUserProfile() 前执行;要保证获取 sessionKey 在getUserProfile 之前,不然就会出现解密失败的问题;
2、在wx.logon() 的 success 回调中包裹 wx.getUserProfile,来保证获取code 和 获取 encryptedData,从而避免解密失败,但是官网明确规定,wx.getUserProfile() 只能通过tap点击去出发,不然就error:getUserProfile:fail can only be invoked by user TAP gesture
3、参考网上做法 把wx.login() 放在 wx.getUserProfile() 的success 回调中去执行,发现还是会出现偶发性的 解密失败;
实现:通过Promise串行保证顺序执行
Tips: 由于是使用uniapp 进行开发,写法和 小程序的语法不太一样,但是思路都是一样的
export default{ data(){ return{ } }, methods:{ getUserProfile() { return new Promise((resolve, reject) => { uni.getUserProfile({ desc: '獲取您的昵稱、頭像、地區及性別', success: userRes => { console.log('getUserProfile-res', userRes); resolve(userRes); }, fail: userErr => { uni.showToast({ title: '授權失敗', icon: 'error' }); console.log('getUserProfile-err', userErr); reject(userErr); } }); }); }, getLoginCode() { return new Promise((resolve, reject) => { uni.login({ provider: 'weixin', success: loginRes => { console.log('loginRes', loginRes); resolve(loginRes); } }); }); }, } }
html中绑定click事件
<button @click.stop="goLogin" class="bottom-btn" type="default" size="mini">登入</button>
goLogin方法中使用promise.all 来保证顺序执行
export default{ data(){ return{ } }, methods:{ goLogin() { // 注意使用函数的写法,避免出现错误 let userProFile = this.getUserProfile(); let loginCode = this.getLoginCode(); loginCode .then(code => { return code; }) .then(logCode => { return new Promise((resolve, reject) => { userProFile .then(res => { resolve({ logCode, iv: res.iv, rawData: res.rawData, encryptedData: res.encryptedData, signature: res.signature }); }) .catch(err => { reject(err); }); }); }) .then(res => { console.log('promise-res', res); }) .catch(err => { console.log('userProfile-err', err); }); } } }
这样经过几天的间断性测试没有出现偶发的 解密失败的问题!