微信小程序用户头像昵称获取新方案:告别wx.getUserProfile后的实战指南

发布时间:2026/6/27 10:18:38

微信小程序用户头像昵称获取新方案:告别wx.getUserProfile后的实战指南 1. 微信小程序用户头像昵称获取的现状与挑战最近不少开发者发现原本在小程序中获取用户头像和昵称的功能突然失效了。这主要是因为微信官方收回了wx.getUserProfile接口的调用权限。这个接口曾经是获取用户信息的万能钥匙现在突然不能用了让很多开发者措手不及。我在实际项目中也遇到了这个问题。记得那天早上刚到公司就收到用户反馈说登录后头像显示不出来。排查后发现是wx.getUserProfile接口返回了错误。这种情况在技术迭代中很常见但确实会给开发者带来不小的麻烦。微信做出这个调整主要是出于用户隐私保护的考虑。现在获取用户信息需要更加谨慎必须采用新的方案。好消息是微信提供了替代方案 - 头像昵称填写能力。这个新方案让用户可以主动选择是否提供头像和昵称而不是开发者直接获取。2. 基础库版本判断与兼容处理2.1 为什么要判断基础库版本新方案需要小程序基础库版本在2.21.2以上才能支持。这就意味着我们需要先判断用户当前使用的基础库版本再决定采用哪种获取方式。这就像买手机时要先看系统版本一样不同版本支持的功能可能不同。我在项目中是这样实现的// 在App.vue中 // #ifdef MP const version uni.getSystemInfoSync().SDKVersion if (compareVersion(version, 2.21.2) 0) { this.$Cache.set(MP_VERSION_ISNEW, true) } else { this.$Cache.set(MP_VERSION_ISNEW, false) } // #endif2.2 版本比较函数的实现你可能注意到了上面的compareVersion函数。这个函数用来比较两个版本号的大小实现起来也不复杂function compareVersion(v1, v2) { v1 v1.split(.) v2 v2.split(.) const len Math.max(v1.length, v2.length) while (v1.length len) v1.push(0) while (v2.length len) v2.push(0) for (let i 0; i len; i) { const num1 parseInt(v1[i]) const num2 parseInt(v2[i]) if (num1 num2) return 1 if (num1 num2) return -1 } return 0 }这个函数会返回1、-1或0分别表示第一个版本大于、小于或等于第二个版本。3. 登录流程的重构与实现3.1 新的登录流程设计在新的方案下登录流程需要做一些调整。我们不能再依赖wx.getUserProfile来获取用户信息了而是要先获取code然后通过后端接口换取用户标识。userLogin() { Routine.getCode() .then(code { uni.showLoading({ title: 正在登录中 }) authLogin({ code, spread_spid: app.globalData.spid, spread_code: app.globalData.code }).then(res { if (res.data.key ! undefined res.data.key) { uni.hideLoading() this.authKey res.data.key this.isPhoneBox true } else { uni.hideLoading() let time res.data.expires_time - this.$Cache.time() this.$store.commit(LOGIN, { token: res.data.token, time: time }) this.getUserInfo() } }) }) .catch(err { console.log(err) }) }3.2 后端接口的实现后端需要新增一个接口来处理静默登录/** * code生成用户 * returns {*} */ export function authLogin(data) { return request.get(v2/wechat/silence_auth_login, data, { noAuth: true }) }这个接口会接收前端传来的code然后向微信服务器换取用户的openid等信息。如果用户是首次登录后端会创建新用户记录如果是老用户就直接返回对应的用户信息。4. 头像昵称填写能力的实现4.1 头像获取的新方式现在获取用户头像需要使用button组件的open-typechooseAvatar属性。当用户点击这个按钮时会触发头像选择事件。button v-ifmp_is_new open-typechooseAvatar chooseavataronChooseAvatar classavatar-wrapper image :srcuserInfo.avatar classavatar/image /button对应的处理函数onChooseAvatar(e) { const { avatarUrl } e.detail this.$util.uploadImgs(upload/image, avatarUrl, (res) { this.userInfo.avatar res.data.url }, (err) { console.log(err) }) }4.2 图片上传工具函数的实现我们需要一个工具函数来处理图片上传uploadImgs(uploadUrl, filePath, successCallback, errorCallback) { let that this uni.uploadFile({ url: HTTP_REQUEST_URL /api/ uploadUrl, filePath: filePath, fileType: image, name: pics, formData: { filename: pics }, header: { // #ifdef MP Content-Type: multipart/form-data, // #endif [TOKENNAME]: Bearer store.state.app.token }, success: (res) { uni.hideLoading() if (res.statusCode 403) { that.Tips({ title: res.data }) } else if (res.statusCode 413) { that.Tips({ title: 上传图片失败,请重新上传小尺寸图片 }) } else { let data res.data ? JSON.parse(res.data) : {} if (data.status 200) { successCallback successCallback(data) } else { errorCallback errorCallback(data) that.Tips({ title: data.msg }) } } }, fail: (err) { uni.hideLoading() that.Tips({ title: 上传图片失败 }) } }) }4.3 昵称获取的实现获取昵称的方式也变了现在需要使用input组件的typenickname属性input v-ifmp_is_new typenickname v-modeluserInfo.nickname classnickname-input placeholder请输入昵称 /这样用户在输入框中输入的内容就会自动作为昵称使用。这种方式比之前更加透明用户清楚地知道自己在提供什么信息。5. 兼容性处理与降级方案5.1 旧版本的处理对于那些基础库版本低于2.21.2的用户我们需要提供一个降级方案。在我的项目中我是这样处理的// 在data中 data() { return { mp_is_new: this.$Cache.get(MP_VERSION_ISNEW) || false, // 其他数据... } }然后在模板中根据这个标志位显示不同的UItemplate !-- 新版本方式 -- div v-ifmp_is_new !-- 新版本的头像昵称获取UI -- /div !-- 旧版本方式 -- div v-else !-- 旧版本的提示或其他获取方式 -- /div /template5.2 用户体验优化为了不给用户造成困惑我们需要做好提示工作。当用户使用旧版本时可以提示他们升级微信客户端if (!this.mp_is_new) { uni.showModal({ title: 提示, content: 您的微信版本较低部分功能可能无法使用建议升级到最新版本, showCancel: false }) }在实际项目中我发现这种提示不能太频繁否则会影响用户体验。可以考虑只在用户第一次遇到这个问题时提示或者提供一个不再提示的选项。6. 实际开发中的注意事项6.1 权限声明的变化在新的方案下我们不再需要scope.userInfo权限声明。这是因为现在获取用户信息的方式变成了用户主动填写而不是开发者直接获取。这个变化在app.json中体现为可以移除对应的权限声明。6.2 用户拒绝处理现在用户可能会拒绝提供头像或昵称我们需要处理好这种情况。可以在获取用户信息时检查是否为空if (!this.userInfo.avatar || !this.userInfo.nickname) { uni.showToast({ title: 请完善头像和昵称, icon: none }) return }6.3 数据同步问题由于头像和昵称现在是分开获取的可能会出现数据不同步的情况。比如用户上传了头像但没有设置昵称。为了解决这个问题我通常在提交时做完整检查submitUserInfo() { if (!this.userInfo.avatar) { uni.showToast({ title: 请上传头像, icon: none }) return } if (!this.userInfo.nickname || this.userInfo.nickname.trim() ) { uni.showToast({ title: 请输入昵称, icon: none }) return } // 提交逻辑... }7. 性能优化与最佳实践7.1 图片上传优化头像上传可能会成为性能瓶颈特别是当用户选择高清图片时。我通常会做以下优化客户端压缩在上传前对图片进行压缩限制图片大小建议用户上传不超过2MB的图片使用CDN加速上传后的图片存储在CDN上// 在uni.chooseImage中增加sizeType参数 uni.chooseImage({ count: 1, sizeType: [compressed], // 压缩图 sourceType: [album, camera], success: (res) { const tempFilePaths res.tempFilePaths // 处理图片... } })7.2 缓存策略为了减少重复上传可以实现本地缓存策略// 在onChooseAvatar中 onChooseAvatar(e) { const { avatarUrl } e.detail // 先检查缓存 const cachedAvatar this.$Cache.get(user_avatar) if (cachedAvatar cachedAvatar.timestamp Date.now() - 24*60*60*1000) { this.userInfo.avatar cachedAvatar.url return } // 没有缓存或缓存过期上传新头像 this.$util.uploadImgs(upload/image, avatarUrl, (res) { this.userInfo.avatar res.data.url // 更新缓存 this.$Cache.set(user_avatar, { url: res.data.url, timestamp: Date.now() }) }) }7.3 错误处理与重试机制网络请求可能会失败特别是图片上传这种操作。实现一个简单的重试机制可以提升用户体验uploadAvatarWithRetry(avatarUrl, retryCount 3) { return new Promise((resolve, reject) { const doUpload (attempt 1) { this.$util.uploadImgs(upload/image, avatarUrl, (res) resolve(res), (err) { if (attempt retryCount) { reject(err) } else { setTimeout(() doUpload(attempt 1), 1000 * attempt) } } ) } doUpload() }) }8. 测试与调试技巧8.1 多版本测试由于这个功能与基础库版本强相关测试时需要覆盖不同版本最新版本测试验证新功能是否正常工作边界版本测试测试2.21.2版本的表现旧版本测试验证降级方案是否有效8.2 真机调试微信开发者工具可能无法完全模拟真机环境特别是权限相关的功能。我通常会在多个真机设备上测试覆盖不同操作系统版本测试不同网络环境下的表现8.3 错误监控实现错误监控可以帮助快速发现问题// 在app.vue中 onError(err) { // 上报错误到监控系统 reportError(err) // 开发环境下打印错误 if (process.env.NODE_ENV development) { console.error(err) } }在实际项目中我发现这种监控对于及时发现和解决用户遇到的问题非常有帮助。特别是当微信有版本更新时可以第一时间知道是否影响了我们的功能。

相关新闻