小程序
小游戏
企业微信
微信支付
扫描小程序码分享
mac 模拟器1.05.2102010 基础库2.16.0
调用wx.login获取code后,再调用wx.getUserProfile,可能会失败,触发fail函数,error msg: ''getUserProfile:fail can only be invoked by user TAP gesture"。
如果不能同时使用,那如何校验用户信息的准确性或者解密encryptedData呢?
20 个回答
加粗
标红
插入代码
插入链接
插入图片
上传视频
用了promise.all(),平级调用
你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。
error msg: ''getUserProfile:fail can only be invoked by user TAP gesture"
这个问题根本不是 wx.login 和 wx.getUserProfile 的调用顺序问题,而是 wx.getUserProfile 不允许自动触发,必须通过用户点击触发(如何使用冒泡等让用户点击是另外一回事)。所以如果 wx.login 是在页面载入时候自动触发的,这时候就不能用 wx.getUserProfile,再加上现在新上线的小程序对于授权提示已经要求比较严了。
这篇文章供参考:https://www.cnblogs.com/szw/p/14632314.html
wx.getUserProfile 用户才能触发,wx.login 不需要用户触发
如果让我们重新设计用户登陆模块,会怎么设计呢?
如果是我的话,我会这样设计:
1.用 wx.login 获取 openId(unionId),这个过程是静默的,不需要用户参与,这个能满足市场大多数应用的需求
2.对于社交分享类的应用,可以进入首页后,用户点击首页可点击区域时,申请用户头像信息(申请成功后保存到后端)
3.在我的页面在增加个用户头像更新能力即可
4.对于分享无法获取实时头像的问题,可以在用户点击分享时,先申请获取用户最新头像,然后在进行分享
这段时间社区很多人吐槽,其实我们还是要看这些改到背后的事情1.对用户隐私要求越来越严,权限细分越来越细,我觉得是好事
2.我们要抛出历史包袱去想用户授权,别被历史包袱所束缚
3.getUserInfo 的能力可以通过 wx.login 和 wx.getUserProfile 来实现,都是只需要用户操作一次,唯一的弊端是 wx.getUserProfile 每次都需要用户触发才能拿到最新头像
4.我觉得没有几个应用对头像的更新频次比微信本身要高,所以也不用在纠结了头像是否为最新的了,只需要提供用户具有更新头像的能力即可
1.网上的promise.all的方式处理,我没试但是我感觉是不行的。all只是把login和getinfo同时运行罢了,但是这两个实际都是异步,到底哪个先触发实际是没法确定的。
2.我这里搞了个比较巧妙的方式,是Taro当然微信原生的代码也是一样的处理方式,原理相同。
getInfo= async()=>{
var res = await Taro.getUserProfile({desc:this.login()})
console.log(res);
}
login = ()=>{
Taro.login().then((res)=>{console.log(res);})
return '用于完善会员资料';
这样login一定比getUserProfile先执行,后面同时拿到两个接口的结果,丢给服务器就行。这个解密失败的问题,一定要保证login的网络请求先getUserProfile到达,然后微信服务器才会更新数据。
promise.all同级调用并不能完美解决顺序问题。
用promise串行,完整代码实现:https://viencoding.com/article/300
代码片段:
wxLogin:function (e) { // 注意,一定要用这种把函数定义成变量的方式,不要直接用,否则就会出现[getUserProfile:fail can only be invoked by user TAP gesture]的错误 let p1 = wxSilentLogin() let p2 = wxGetUserProfile() p1.then(code => { return code }).then(code => { return new Promise((resolve, reject) => { p2.then(res => { resolve({code, iv: res.iv, encryptedData: res.encryptedData}) }).catch(err => { reject(err) }) }) }).then(res => { // 请求服务器 wx.request({ url: 'https://viencoding.com/api/v1/wx/login', method: 'post', data: { code: res.code, encrypted_data: res.encryptedData, iv: res.iv }, header: { 'content-type': 'application/json' // 默认值 }, success (res) { console.log(res.data) // 这里是登陆成功服务器返回值 } }) }).catch((err) => { console.log(err) }) }
我使用 uniapp 开发的,但可以借鉴下。初学者,如有错误请见谅!
用wx.login获取code后在回调里发起一个弹窗用于触发wx.getUserProfile
代码如下:
wx.login({ success(res) { if (res.code) { const code = rs.code; uni.request({//获取openID url: 'https://jiudaotian.cn', //仅为示例,并非真实接口地址。 data: {code: code}, success: (rs) => {//返回状态来判断是否授权过了 uni.showModal({ title: '提示', content: '检查到您是首次使用小程序,我们希望获得您的个人信息,以便为您提供更好的服务!', showCancel: false, success: function(res) { if (res.confirm) { wx.getUserProfile({ desc: '用于完善用户资料', success: (res) => { } }); } } }); } }); } } });
可以先调用getUserProfile再调用wx.login
https://blog.csdn.net/weixin_42289080/article/details/120001198 使用实例,欢迎参考,希望帮到你
不要把这些方法放在setTimeout里调用,比如包裹防抖函数等
我的解决思路:
用户点击登录后,调用函数bindtap="getUserProfile"。
getUserProfile: function(e){
wx.login() //获取code
wx.getUserProfile( //获取授权信息
//success成功后执行以下操作:
//先弹出一个wx.showToast,延迟时间duration为2秒,目的让用户看到程序正在执行,提高用户体验
//设置一个定时3秒后执行submitLogin()函数:setTimeout(submitLogin(), 3000),目的是使得wx.login()执行完毕生成code
)
},
submitLogin(){ // 赋值code + 授权信息,然后提交
wx.request() 提交api
正在加载...
关注后,可在微信内接收相应的重要提醒。
请使用微信扫描二维码关注 “微信开放社区” 公众号
用了promise.all(),平级调用
error msg: ''getUserProfile:fail can only be invoked by user TAP gesture"
这个问题根本不是 wx.login 和 wx.getUserProfile 的调用顺序问题,而是 wx.getUserProfile 不允许自动触发,必须通过用户点击触发(如何使用冒泡等让用户点击是另外一回事)。所以如果 wx.login 是在页面载入时候自动触发的,这时候就不能用 wx.getUserProfile,再加上现在新上线的小程序对于授权提示已经要求比较严了。
这篇文章供参考:https://www.cnblogs.com/szw/p/14632314.html
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
删了呢,就不会出发wx.login了,官方给的示例代码是有问题的吗,为啥都不用啊
wx.login({
success (res) {
if (res.code) {
//发起网络请求
wx.request({
url: 'https://example.com/onLogin',
data: {
code: res.code
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
wx.getUserProfile 用户才能触发,wx.login 不需要用户触发
如果让我们重新设计用户登陆模块,会怎么设计呢?
如果是我的话,我会这样设计:
1.用 wx.login 获取 openId(unionId),这个过程是静默的,不需要用户参与,这个能满足市场大多数应用的需求
2.对于社交分享类的应用,可以进入首页后,用户点击首页可点击区域时,申请用户头像信息(申请成功后保存到后端)
3.在我的页面在增加个用户头像更新能力即可
4.对于分享无法获取实时头像的问题,可以在用户点击分享时,先申请获取用户最新头像,然后在进行分享
这段时间社区很多人吐槽,其实我们还是要看这些改到背后的事情1.对用户隐私要求越来越严,权限细分越来越细,我觉得是好事
2.我们要抛出历史包袱去想用户授权,别被历史包袱所束缚
3.getUserInfo 的能力可以通过 wx.login 和 wx.getUserProfile 来实现,都是只需要用户操作一次,唯一的弊端是 wx.getUserProfile 每次都需要用户触发才能拿到最新头像
4.我觉得没有几个应用对头像的更新频次比微信本身要高,所以也不用在纠结了头像是否为最新的了,只需要提供用户具有更新头像的能力即可
1.网上的promise.all的方式处理,我没试但是我感觉是不行的。all只是把login和getinfo同时运行罢了,但是这两个实际都是异步,到底哪个先触发实际是没法确定的。
2.我这里搞了个比较巧妙的方式,是Taro当然微信原生的代码也是一样的处理方式,原理相同。
getInfo= async()=>{
var res = await Taro.getUserProfile({desc:this.login()})
console.log(res);
}
login = ()=>{
Taro.login().then((res)=>{console.log(res);})
return '用于完善会员资料';
}
这样login一定比getUserProfile先执行,后面同时拿到两个接口的结果,丢给服务器就行。这个解密失败的问题,一定要保证login的网络请求先getUserProfile到达,然后微信服务器才会更新数据。
promise.all同级调用并不能完美解决顺序问题。
用promise串行,完整代码实现:https://viencoding.com/article/300
代码片段:
wxLogin:function (e) { // 注意,一定要用这种把函数定义成变量的方式,不要直接用,否则就会出现[getUserProfile:fail can only be invoked by user TAP gesture]的错误 let p1 = wxSilentLogin() let p2 = wxGetUserProfile() p1.then(code => { return code }).then(code => { return new Promise((resolve, reject) => { p2.then(res => { resolve({code, iv: res.iv, encryptedData: res.encryptedData}) }).catch(err => { reject(err) }) }) }).then(res => { // 请求服务器 wx.request({ url: 'https://viencoding.com/api/v1/wx/login', method: 'post', data: { code: res.code, encrypted_data: res.encryptedData, iv: res.iv }, header: { 'content-type': 'application/json' // 默认值 }, success (res) { console.log(res.data) // 这里是登陆成功服务器返回值 } }) }).catch((err) => { console.log(err) }) }
我使用 uniapp 开发的,但可以借鉴下。初学者,如有错误请见谅!
用wx.login获取code后在回调里发起一个弹窗用于触发wx.getUserProfile
代码如下:
wx.login({ success(res) { if (res.code) { const code = rs.code; uni.request({//获取openID url: 'https://jiudaotian.cn', //仅为示例,并非真实接口地址。 data: {code: code}, success: (rs) => {//返回状态来判断是否授权过了 uni.showModal({ title: '提示', content: '检查到您是首次使用小程序,我们希望获得您的个人信息,以便为您提供更好的服务!', showCancel: false, success: function(res) { if (res.confirm) { wx.getUserProfile({ desc: '用于完善用户资料', success: (res) => { } }); } } }); } }); } } });
可以先调用getUserProfile再调用wx.login
但是放在wx.login之后,又弹不出授权窗口,真的是两难。
https://blog.csdn.net/weixin_42289080/article/details/120001198 使用实例,欢迎参考,希望帮到你
不要把这些方法放在setTimeout里调用,比如包裹防抖函数等
我的解决思路:
用户点击登录后,调用函数bindtap="getUserProfile"。
getUserProfile: function(e){
wx.login() //获取code
wx.getUserProfile( //获取授权信息
//success成功后执行以下操作:
//先弹出一个wx.showToast,延迟时间duration为2秒,目的让用户看到程序正在执行,提高用户体验
//设置一个定时3秒后执行submitLogin()函数:setTimeout(submitLogin(), 3000),目的是使得wx.login()执行完毕生成code
)
},
submitLogin(){ // 赋值code + 授权信息,然后提交
wx.request() 提交api
}