小程序
小游戏
企业微信
微信支付
扫描小程序码分享
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呢?
23 个回答
加粗
标红
插入代码
插入链接
插入图片
上传视频
用了promise.all(),平级调用
你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。
可以直接按顺序执行login和getUserProfile方法,因为getUserProfile方法需要用户点击确认后才能获取到用户信息,这时候login方法已经执行完毕了,所以不需要考虑异步回调的问题。代码如下
// 执行登录操作 let code = ''; wx.login({ success:(res) => { code = res.code; }, }); // 获取用户信息 wx.getUserProfile({ lang: 'zh_CN', desc: '用户登录', success: (res) => { let loginParams = { code: code, encryptedData: res.encryptedData, iv: res.iv, rawData: res.rawData, signature: res.signature }; _this.postLogin(loginParams); }, // 失败回调 fail: () => { // 弹出错误 App.showError('已拒绝小程序获取信息'); } });
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里调用,比如包裹防抖函数等
正在加载...
关注后,可在微信内接收相应的重要提醒。
请使用微信扫描二维码关注 “微信开放社区” 公众号
用了promise.all(),平级调用
可以直接按顺序执行login和getUserProfile方法,因为getUserProfile方法需要用户点击确认后才能获取到用户信息,这时候login方法已经执行完毕了,所以不需要考虑异步回调的问题。代码如下
// 执行登录操作 let code = ''; wx.login({ success:(res) => { code = res.code; }, }); // 获取用户信息 wx.getUserProfile({ lang: 'zh_CN', desc: '用户登录', success: (res) => { let loginParams = { code: code, encryptedData: res.encryptedData, iv: res.iv, rawData: res.rawData, signature: res.signature }; _this.postLogin(loginParams); }, // 失败回调 fail: () => { // 弹出错误 App.showError('已拒绝小程序获取信息'); } });
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里调用,比如包裹防抖函数等