Skip to content
On this page

案例一: 头像获取

首先我们看一下微信官方对头像获取做出的改动日志:

open-type=“getUserInfo” 在2021年4月13日停用
wx.getUserInfo 在2021年4月28日停用
wx.getUserProfile 在2022年11月8日停用

1. 起因

鉴于微信小程序的接口改动,开发者无法使用getUserProfile接口获取用户头像(代码如下),导致我们开发者不得不探索其他获取用户头像的方法。

js
getUserProfile(e) {
    // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
    // 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
    wx.getUserProfile({
      desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
        wx.setStorage({
          data: res.userInfo,
          key: 'userInfo',
        })
      }
    })
    app.getUnionId()
  },

2. 解决思路

2.1 wxml部分

wxml方面,我改为采用bind:chooseavatar的形式获取用户头像,具体可见代码的setting.wxml部分

2.2 js部分

在js方面,由于这个新的获取方式会返回一个临时的图片url地址,而这个地址无法直接使用,因此我提出了如下两种解决办法:

方法1

后端为主

利用wx.uploadFile接口将这个临时地址转换为base64格式传递给后端,同时传递一个unionId做唯一标识,之后再使用时由后端传递给前端url地址就可以获得了; 这个方法的主要难度在后端,需要后端接收base64格式,返回url格式,并且还要检验传递的图片是否过大等等,我在实际操作中遇到了一些问题,所以舍弃了这种方法,大家有兴趣的可以尝试一下

方法2

前端为主,对临时地址进行两次转换,获得可用的本地url,两次转换如下,具体转换函数可见代码的js部分

  1. 将bind:chooseavatar返回的临时图片url转换为base64格式,存储在storage里, 使用函数ImgToBase64Func
  2. 将base64格式的图片转换为本地url,也存储在storage里, 使用函数base64src.js

在进行两轮转换后,我获得了本地的图片url地址并存储到了微信小程序的缓存中,当需要展示的时候直接从缓存中获取即可

这种方法的优点是不需要判断用户传递的图片是否过大,减少了后端的工作量,减轻了服务器压力

3. 代码部分

3.1 utils/base64src.js

将base64格式的图片转换为本地url, 便于直接在image标签中展示

js
const fsm = wx.getFileSystemManager();
const FILE_BASE_NAME = 'avatar'; //自定义文件名

function base64src(base64data, cb) {
  const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
  if (!format) {
    return (new Error('ERROR_BASE64SRC_PARSE'));
  }
  const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
  const buffer = wx.base64ToArrayBuffer(bodyData);
  fsm.writeFile({
    filePath,
    data: buffer,
    encoding: 'binary',
    success() {
      cb(filePath);
    },
    fail() {
      return (new Error('ERROR_BASE64SRC_WRITE'));
    },
  });
};

export { base64src };

3.2 setting.wxml

js
<button class="avatar-wrapper xl margin-tb" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
    <image class="avatar" src="{{avatarUrl}}"></image>
  </button>

3.3 setting.js

js
import { base64src } from '../../utils/base64src'
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'

Page({
  data: {
    avatarUrl: defaultAvatarUrl // 用户头像
  },
  
  // onShow
  onShow() {
    console.log("setting | onShow")
    var me = this
    me.setData({
      avatarUrl: wx.getStorageSync('avatar')
    })
  },

  // 将临时图片url转换为base64格式的图片
  ImgToBase64Func(filePath) {
    return new Promise((resolve, reject) => {
      let baseFormat = 'data:image/png;base64,'
      let base64 = wx.getFileSystemManager().readFileSync(filePath, 'base64')
      resolve(baseFormat + base64)
    })
  },

  // 获取并存储用户头像: avatarUrl(临时url) -> res(base64) -> result(本地url)
  onChooseAvatar(e) {
    var me = this
    // 从事件对象中解构出avatarUrl
    const { avatarUrl } = e.detail 
    console.log("avatarUrl:",avatarUrl);
    me.setData({
      avatarUrl
    })
    // 将这个临时的avatarUrl转换为base64格式,并存储在storage里, key="avatar_base64"
    me.ImgToBase64Func(avatarUrl).then(res=>{
      console.log('base64格式的图片: ',res)
      wx.setStorage({
        key:"avatar_base64",
        data:res
      })
      // 将base64格式的图片转换为本地url,同样存储在storage里, key="avatar"
      base64src(res, result => {
        console.log("url格式的图片: ",result) // 返回图片地址,直接赋值到image标签即可
        wx.setStorageSync('avatar', result)
        wx.reLaunch({
          url: '../homepage/homepage',
          success(res){
            console.log("跳转成功: ",res)
            wx.showToast({
              title: '修改成功',
            })
          }
        })
      });
    })
  },
})

可以使用下面的网址检验临时url是否成功转换为base64格式

BASE64转图片 - 站长工具 - 极速数据 (jisuapi.com)

上次更新于: