微信分享
原理:
我们后台将
noncestr(随机32以内的字符串)、
url(当前的url页面,不包含#后面的,不要转义url)、
jsapi_ticket(票据)、
timestamp(时间戳)
这几个参数按首字母排序后用 & 拼接成键=值的形式,和get传参一样,拼接后得到一串字符串,
然后用 sha1 进行加密签名,将这几个参数(包含签名后的 sign 字符串)传给前端,
前端将参数按照微信规则封装成对象调用微信提供的 wx.config() 方法,
微信会对这几个参数和当前的url进行签名验证,如果验证成功会调用 wx.ready() 方法
注意:
- 我前端使用的是 vue,所以url会有 # 号,我们传给后端签名的 url 是要获取 当前 url # 号前面的部分
- 分享的图片链接要使用绝对路径
- 我们要保证 我们后端签名的 url 和微信自动获取的当前 url 要一致,这个是重中之重
- 当前分享页面的域名一定要在 微信公众号平台有配置
代码开始
1. 配置公众号安全域名,这个自行百度
2. 引入微信提供的 jssdk
// 以下两个随便引入一个即可
https://res.wx.qq.com/open/js/jweixin-1.6.0.js
https://res2.wx.qq.com/open/js/jweixin-1.6.0.js
3. 前端获取当前的 url 当成参数请求后端签名
// ajax 方法自己编写,url 这样获取就行
url: location.href.split('#')[0]
4. 后端接收 url 后按照微信规则进行签名返回
@GetMapping("/getShareOption") public R getShareOption(String url) {
// 获取10位时间戳 String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
// 随机字符串,可自行设置,我这里使用的是微信提供的依赖 String noncestr = WXPayUtil.generateNonceStr();
// 临时票据,获取这个票据需要先获取微信的 accessToken, 这个百度一下,多的是答案 String ticket = weChatUtils.getTicket();
// 公众号id, 微信公众号平台提供的 String appId = config.getWeChatAppId();
// 用 map 封装 Map<String, String> map = new HashMap<>(); map.put("noncestr", noncestr); map.put("url", url); map.put("jsapi_ticket", ticket); map.put("timestamp", timeStamp); Set<String> keySet = map.keySet(); String[] keyArray = keySet.toArray(new String[keySet.size()]);
// 排序, 这个是关键 Arrays.sort(keyArray); StringBuilder sb = new StringBuilder();
// 用 & 拼接键值对 for (String k : keyArray) { if (map.get(k).trim().length() > 0) // 参数值为空,则不参与签名 sb.append(k).append("=").append(map.get(k).trim()).append("&"); } String str = sb.toString(); if(str.endsWith("&")){ str = str.substring(0, str.length() - 1); } log.info("签名参数:{}", str); String signature = DigestUtils.sha1Hex(str); log.info("签名后的值:{}", signature);
// 将这几个参数 返给前端 return R.ok().put("appId", appId).put("timestamp", timeStamp).put("noncestr", noncestr).put("signature", signature); }
5. 前端接收到返回值后,调用 wx.config() 方法
// 微信一键分享方法,mounted 钩子内执行 fetchWechatShareParams () { this.$http({ url: this.$http.adornUrl('/weChat/getShareOption'), method: 'GET', params: this.$http.adornParams({ url: location.href.split('#')[0] }) }).then(({ data }) => { let d = data.appId let i = data.timestamp let t = data.noncestr let n = data.signature
// 调用这个方法后,微信会验证我们的签名和微信的签名是否一致,是则成功,否则失败 window.wx.config({ debug: false, // 如果分享失败,把0改成1开启错误提示看看 appId: d, timestamp: i, nonceStr: t, signature: n, jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage'] })
// 微信验签成功后才会调用这个方法 window.wx.ready(function () { window.wx.onMenuShareTimeline({ title: '分享标题', desc: '分享描述', link: '分享链接,这个不需要一定和当前的 url 一样,有 # 没问题,是一个完整可访问的 url', imgUrl: '图片地址,绝对路径' }) window.wx.onMenuShareAppMessage({ title: '分享标题', desc: '分享描述', link: '分享链接,这个不需要一定和当前的 url 一样, 有 # 没问题,是一个完整可访问的 url', imgUrl: '图片地址,绝对路径' }) }) }) }
不懂可以加我 QQ: 287475833
只要你不觉得尴尬,那尴尬的就是别人