uni-app使用微信JS-SDK

记录如何在uni-app中使用微信JS-SDK

前段时间因为修改bug的原因学习了下如何在uni-app下面使用多图上传,所以基于uni-app做了一个微信JS-SDK调用的Demo

依赖安装

  • npm命令方式
npm install jweixin-module --save

这里我们使用了非npm安装的方式

页面引用

在需要使用微信JS-SDK功能的页面引入


<script>
function getLocalImgDataPromise(localId) {
    return new Promise((resolve, reject) => {
        wx.getLocalImgData({
            localId: localId,
            success: function(res) {
                resolve(res)
            },
            fail: function(err) {
                reject(err)
            }
        });
    })
}

import wx from '@/common/js/jweixin-module/index.js'
export default {
    data() {
        return {
            upload_picture_list: []
        }
    },
    onLoad() {
        //获取微信公众号的配置
        uni.request({
            url: 'http://localhost:4000/sig',
            data: {
                url: location.href.split('#')[0]
            },
            success: res => {
                var s = res.data;
                wx.config({
                    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: s.data.appId, // 必填,公众号的唯一标识
                    timestamp: s.data.timestamp, // 必填,生成签名的时间戳
                    nonceStr: s.data.noncestr, // 必填,生成签名的随机串
                    signature: s.data.signature.toLowerCase(), // 必填,签名,见附录1
                    jsApiList: [
                        'chooseImage',
                        'previewImage',
                        "getLocalImgData",
                        'uploadImage',
                    ]
                });
                if (typeof callback === 'function') {
                    callback(res.data);
                }
                wx.ready(() => {
                    wx.checkJsApi({
                        // 需要检测的JS接口列表
                        jsApiList: ['chooseImage'],
                        success: function(res) {
                            console.log("res: " + res);
                        }
                    });
                })
            },
            fail: err => {
                console.log('request fail', err);
            }
        });

    },
    methods: {
        previewImg(index) {
            let that = this
            uni.previewImage({
                current: index,
                urls: that.upload_picture_list
            });
        },
        chooseImage() {
            let _this = this
            wx.chooseImage({
                success: async (res) => {
                    let localIds = res.localIds;
                    for (let i = 0, len = localIds.length; i < len; i++) {
                        let imgDataRes = await getLocalImgDataPromise(localIds[i])
                        const localData = imgDataRes.localData
                        let imageBase64 = '';
                        if (localData.indexOf('data:image') == 0) {
                            //苹果的直接赋值,默认生成'data:image/jpeg;base64,'的头部拼接
                            imageBase64 = localData;
                        } else {
                            //此处是安卓中的唯一得坑!在拼接前需要对localData进行换行符的全局替换
                            //此时一个正常的base64图片路径就完美生成赋值到img的src中了
                            imageBase64 = 'data:image/jpeg;base64,' + localData.replace(
                                /\n/g, '');
                        }
                        _this.upload_picture_list.push(imageBase64);
                    }
                }
            });
        }
    }
}
</script>

后台签名方法(nodejs)

这里我们使用koa框架来实现签名,详情可以参考上次分享的文章基于koa实现的微信JS-SDK调用Demo
uni-app项目根目录下的server文件夹下即为示例后端代码,执行node app.js即可,下面是签名核心方法:


router.get('/sig', async (ctx, next) => {
  try {
    //获取当前url
    let url =
      ctx.request.protocol + '://' + ctx.request.host + ctx.request.originalUrl;
    if (ctx.query.url) {
      url = ctx.query.url;
    }
    ctx.data = await sign(url);
  } catch (e) {
    console.log(e);
  }
  await next();
});

async function sign(url) {
  let sig = {},
    noncestr = config.noncestr,
    timestamp = Math.floor(Date.now() / 1000), //精确到秒
    jsapi_ticket;
  if (cache.get('ticket')) {
    jsapi_ticket = cache.get('ticket');
    sig = {
      appId: config.appid,
      noncestr: noncestr,
      timestamp: timestamp,
      url: url,
      jsapi_ticket: jsapi_ticket,
      signature: sha1(
        'jsapi_ticket=' +
          jsapi_ticket +
          '&noncestr=' +
          noncestr +
          '&timestamp=' +
          timestamp +
          '&url=' +
          url
      ),
    };
  } else {
    // 获取 token
    let tokenRes = await rp({
      uri:
        config.accessTokenUrl +
        '?grant_type=' +
        config.grant_type +
        '&appid=' +
        config.appid +
        '&secret=' +
        config.secret,
    });
    tokenRes = JSON.parse(tokenRes);

    // 获取 ticket
    let ticketRes = await rp({
      uri:
        config.ticketUrl +
        '?access_token=' +
        tokenRes.access_token +
        '&type=jsapi',
    });
    var ticketMap = JSON.parse(ticketRes);
    // 加入缓存
    cache.put('ticket', ticketMap.ticket, config.cache_duration);
    sig = {
      appId: config.appid,
      noncestr: noncestr,
      timestamp: timestamp,
      url: url,
      jsapi_ticket: ticketMap.ticket,
      signature: sha1(
        'jsapi_ticket=' +
          ticketMap.ticket +
          '&noncestr=' +
          noncestr +
          '&timestamp=' +
          timestamp +
          '&url=' +
          url
      ),
    };
  }
  return sig;
}

效果演示

视频演示地址:
https://www.bilibili.com/video/BV1SV411p7Hs?share_source=copy_web

参考资料

(完)