评论

【笔记】解决用户头像过期无法显示问题

解决用户更改头像后,用户头像失效的问题。

小根据官方规则,用户如果修改了头像,那么一段时间之后,用户原始的头像链接会失效。
而因为我们一般用户资料储存的时候只储存了链接,就会造成失效,因此需要把用户头像转换成base64直接存数据库中,这样就不怕失效了。


云开发代码

/**
 * 插入用户数据
 */
function addUserData(openid, userInfo) {
  if (!userInfo) {
    console.log('无用户信息,更新失败')
  }
  // 将头像图片转换为base64
  http.get(userInfo.avatarUrl.replace("https", "http"), function (res) {
    let chunks = []; //用于保存不断加载的缓冲数据
    let size = 0;   //保存缓冲数据的总长度

    res.on('data', function (chunk) {
      chunks.push(chunk); //把接受到的数据逐段保存在缓冲区(Buffer
      size += chunk.length;//累加缓冲数据的长度
    });
    res.on('end', function () {
      var data = Buffer.concat(chunks, size);//Buffer.concat将chunks数组中的缓冲数据拼接起来

      if (Buffer.isBuffer(data)) {
        //如果为Buffer转换为base64并赋值给avatarImg
        var base64Img = 'data:image/png;base64,' + data.toString('base64');
        userInfo.avatarImg = base64Img
      }

      db.collection('user').doc(openid).set({
        data: userInfo
      }).then(e => {
        console.log('用户数据更新成功', e)
      })
    });
  });
}


小程序端直接渲染

<!-- 直接渲染到页面 page.wxml -->
<view style="background-image:url({{detail.avatarImg||detail.avatarUrl}});"></view>


小程序端将图片保存到本地

//如果需要将头像转成图片保存,如cavans绘图场景 page.js
    const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(src) || [];
    if (format) {
      const filePath = `${wx.env.USER_DATA_PATH}/tmp_base64src.${format}`;
      // console.log(filePath)
      // const buffer = wx.base64ToArrayBuffer(bodyData);
      FileSystemManager.writeFile({
        filePath,
        data: bodyData,
        encoding: 'base64',
        success() {
           console.log(filePath)
        },
        fail() {
          console.log (new Error('ERROR_BASE64SRC_WRITE'));
        },
      });
    }


小程序端 已授权用户进入时自动更新

//进入小程序时,自动更新授权用户的信息到云端 app.js
  onLaunch: function () {
    this.getUserAuth();
 }
  getUserAuth: function () {
    wx.getSetting({
      success: res => {
        res.authSetting['scope.userInfo'] && wx.getUserInfo({
          success: res => {

            wx.cloud.callFunction({
              name: 'user',
              data: {
                userData: res.userInfo,
              }
            })

          }
        })
      }
    })
  },



最后一次编辑于  2020-07-07  
点赞 4
收藏
评论

7 个评论

  • 轻兔小程序服务商
    轻兔小程序服务商
    2022-06-17

    可以通过手机号调用获取到头像昵称性别,我这可以实现这样的接口

    2022-06-17
    赞同
    回复
  • 左勇-湘宗
    左勇-湘宗
    2021-11-23

    这点挺烦的,其实微信官方完全可以把用户头像链接固定!

    2021-11-23
    赞同
    回复
  • Ryan
    Ryan
    2021-03-16

    base64是一种编码方式,不建议这样用来编码图片,存储到数据库,一般是存储到图片服务器(公司内部的或者七牛云)

    1.你这样是保留了用户的头像,但是丢失了图片服务器的功能,原图像最后一位 132、64/32这些参数表示图像的大小(132*132)

    2.每个微信头像大约4KB,如果有100万的用户量,就需要将近4G的存储

    2021-03-16
    赞同
    回复 1
    • 驰子
      驰子
      2021-05-19
      谢谢建议~
      2021-05-19
      回复
  • Why先森
    Why先森
    2021-01-12

    base64形式 如果量大会不会影响前端用户性能???

    2021-01-12
    赞同
    回复 1
    • 驰子
      驰子
      2021-01-13
      还好吧,我每次请求用户数据就几十条,没感觉性能问题。你要是有顾虑的话,可以不用base64,存成文件,用URL是一样的。
      2021-01-13
      回复
  • 27
    27
    2020-11-25

    先 mark

    2020-11-25
    赞同
    回复
  • Vincent
    Vincent
    2020-07-02

    你这种做法头像永远都不会更新。用户已授权获取头像之后,后面都能用getUserInfo的接口获取,用已储存的链接和调用getUserInfo获取的链接对比更新不就好了吗

    2020-07-02
    赞同
    回复 1
    • 驰子
      驰子
      2020-09-01
      如果用户不再进入小程序呢?getUserInfo是永远调用不了了,时间长了会造成帖子列表里大量无头像用户。我是每次用户再次进入的时候 会用 getUserInfo 重新调用一下接口 更新下base64,这部分代码已补上。
      2020-09-01
      回复
  • 老张
    老张
    2020-06-01

    有用,先mark.

    2020-06-01
    赞同
    回复
登录 后发表内容