# 微信H5分享

本文相关代码地址:github (opens new window)

这里的分享指的是在微信 APP 内打开的网页分享,JS-SDK (opens new window) 文档

# 后端

需要后端提供微信认证配置参数

  timestamp: '' // 必填,生成签名的时间戳
  nonceStr: '' // 必填,生成签名的随机串
  signature: ''// 必填,签名
1
2
3

服务配置获取流程:

  • 获取 access_token:根据公众号 appIdappsecret 请求接口获取
  • 获取 jsapi_ticket:利用 access_token 获取
  • 计算 signature:根据 jsapi_ticket 排序,拼接,加密获取

# 获取access_token

/**
 * 获取 access_token
 * @param {String} appId 
 * @param {String} appsecret 
 */
async function getAccessToken(appId, appsecret) {
  return fly.get(`${API_ACCESS_TOEN}/token?grant_type=client_credential&appid=${appId}&secret=${appsecret}`)
}
1
2
3
4
5
6
7
8

# 获取 jsapi_ticket

/**
 * 获取 jsapi_ticket
 * @param {String} token 
 */
async function getJsapiTicket(token) {
  return fly.get(`${API_ACCESS_TOEN}/ticket/getticket?access_token=${token}&type=jsapi`)
}
1
2
3
4
5
6
7

# 计算 signature

使用微信提供的计算方法 (opens new window)

var createNonceStr = function () {
  return Math.random().toString(36).substr(2, 15);
};

var createTimestamp = function () {
  return parseInt(new Date().getTime() / 1000) + '';
};

var raw = function (args) {
  var keys = Object.keys(args);
  keys = keys.sort()
  var newArgs = {};
  keys.forEach(function (key) {
    newArgs[key.toLowerCase()] = args[key];
  });

  var string = '';
  for (var k in newArgs) {
    string += '&' + k + '=' + newArgs[k];
  }
  string = string.substr(1);
  return string;
};

/**
* @synopsis 签名算法 
*
* @param jsapi_ticket 用于签名的 jsapi_ticket
* @param url 用于签名的 url ,注意必须动态获取,不能 hardcode
*
* @returns
*/
var sign = function (jsapi_ticket, url) {
  var ret = {
    jsapi_ticket: jsapi_ticket,
    nonceStr: createNonceStr(),
    timestamp: createTimestamp(),
    url: url
  };
  var string = raw(ret);
      jsSHA = require('jssha');
      shaObj = new jsSHA(string, 'TEXT');
  ret.signature = shaObj.getHash('SHA-1', 'HEX');

  return ret;
};

module.exports = sign;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

# 返回配置信息

// 测试公众号信息
const APP_ID = `wx085478e6bb636b0d`
const APP_SECRET = `45269d2ff52d25df203b4fdefbd63f5f`

const API_ACCESS_TOEN = `https://api.weixin.qq.com/cgi-bin`

app.use(async ctx => {
  const ctxUrl = ctx.request.url

  if (ctxUrl.includes('/wechat')) {
    const { url, echostr } = utils.getBodyMessage(ctx)
    if (echostr) {
      ctx.body = echostr;
      return echostr;
    }
    try {
      const { data: { access_token } } = await getAccessToken(APP_ID, APP_SECRET)
      const { data: { ticket } } = await getJsapiTicket(access_token)
      const data = sign(ticket, url)
      console.log(data, access_token, ticket)
      ctx.body = {
        code: 200,
        data: Object.assign({ appId: APP_ID }, data),
        msg: ''
      };
    } catch (error) {
      console.log(error);
    }
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 前端

# 绑定域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。 备注:登录后可在“开发者中心”查看对应的接口权限。

# 引入JS文件


在需要调用JS接口的页面引入如下 JS 文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js (opens new window)
如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (opens new window) (支持https)。
备注:支持使用 AMD/CMD 标准模块加载方法加载

# config 验证配置

wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '', // 必填,公众号的唯一标识
  timestamp: , // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
  jsApiList: [] // 必填,需要使用的JS接口列表
});
1
2
3
4
5
6
7
8

# 回调方法

  • 成功回调
wx.ready(function(){
  // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
1
2
3
  • 失败回调
wx.error(function(res){
  // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
1
2
3

# 分享

  • 分享朋友圈
wx.ready(function () {
  wx.updateTimelineShareData({
    title: title, // 分享标题
    link: link, // 分享链接
    imgUrl: img, // 分享图标
    success: function () {
      // 用户确认分享后执行的回调函数
      alert('用户确认分享')
    },
    cancel: function () {
      // 用户取消分享后执行的回调函数
      alert('用户取消分享')
    },
    complete: function(res) {
      alert(JSON.stringify(res));
    }
  });
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • 分享朋友
// 分享给朋友
wx.updateAppMessageShareData({
  title: title, // 分享标题
  desc: desc, // 分享描述
  link: link, // 分享链接
  imgUrl: img, // 分享图标
  type: '', // 分享类型,music、video或link,不填默认为link
  dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
  success: function (res) {
    // 用户确认分享后执行的回调函数
    alert('用户确认分享朋友')
  },
  cancel: function (res) {
    // 用户取消分享后执行的回调函数
    alert('用户取消分享朋友')
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 注意

1588820770(1).jpg

参考:


欢迎关注公众号,大家一起共同交流和进步。

更新于: 5/21/2020, 1:46:49 AM