Hi,很高兴认识你~
世界很大,巧妙的是我们在这里相遇。
欢迎关注天宇文创意乐派,一个职场人的聚集地。
一.官方教程
官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
官方文档——常见的错误及解决方法:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html ——> 见页面底端的 附录5-常见错误及解决方法
官方问题反馈:https://developers.weixin.qq.com/community/develop/doc/0000e2f5d0cdc02c0a391aedd58c00
官方校验签名工具:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
官方demo:https://www.weixinsxy.com/jssdk/
二.常见问题以及需要注意的地方
1. invalid signature签名错误。建议按如下顺序检查:1. 确认签名算法正确,可用http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。2. 确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。3. 确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。4. 确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。5. 确保一定缓存access_token和jsapi_ticket。6. 确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent,后端接收url时且必须用例如:Java URLDecoder.decode解码),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。2.invalid domain?配置的url与公众号JS接口安全域名不匹配
三.绑定JS接口安全域名


域名格式:如果你的项目域名是http://test.domain.com,那么JS接口安全域名为test.domain.com。切记!
四.引入JSSDK
第一种引入方式:
npm install jweixin-module --save 第二种引入方式:
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
代码实现:
前端
import wx from 'weixin-js-sdk';async _goWxchat(){let url = encodeURIComponent(location.href.split('#')[0]);let data={url}alert(url)const res = await reqConfigSignature(data);if (res.code === RESULT_SUCCESS_CODE) {//拿到后端给的这些数据let appId = res.data.appId;let timestamp = res.data.timestamp;let nonceStr = res.data.nonceStr;let signature = res.data.signature;wx.config({debug: true,// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。appId, // 必填,公众号的唯一标识,填自己的!(开发者账号)timestamp, // 必填,生成签名的时间戳,刚才接口拿到的数据nonceStr, // 必填,生成签名的随机串signature, // 必填,签名,见附录1jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage']})wx.ready(function () {//分享到朋友圈wx.onMenuShareTimeline({title: '小婊子', // 分享时的标题link: url + '?redirectUrl=http://auth.motopa.cn/logo.png', // 分享时的链接 如果项目域名与JS接口安全域名不一致 可以采用此方式imgUrl: '', // 分享时的图标success: function () {console.log("分享成功");},cancel: function () {console.log("取消分享");}});//分享给朋友wx.onMenuShareAppMessage({title: tit,desc: '这件商品终于优惠了,每件只需元',link: url + '?redirectUrl=http://auth.motopa.cn/logo.png',imgUrl: '',type: '',dataUrl: '',success: function () {console.log("分享成功");},cancel: function () {console.log("取消分享");}});})wx.error(function(res){})}},
后端
package com.auth.sdk.controller;import com.alibaba.fastjson.JSONObject;import com.auth.sdk.common.ResultData;import com.auth.sdk.db.redisson.dao.base.StringRedisBaseDao;import lombok.extern.slf4j.Slf4j;import org.apache.commons.codec.digest.DigestUtils;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import java.net.URLDecoder;import java.util.Arrays;import java.util.Random;("/wx")public class WxShareController {private static final String appId = "wxea6631d168a33e95";private static final String appSecret= "3eae75d6a79a9af781391c9c1460026f";private static final long expireTime = 120l;RestTemplate restTemplate;//redis 可以替换成自己环境的redisStringRedisBaseDao stringRedisBaseDao;/*** 获取最终签名的restful方法* @param reqJson* @return*/("/WeixinAction_getWXConfigSignature")public ResultData getWXConfigSignature( JSONObject reqJson) {String url = URLDecoder.decode(reqJson.getString("url"));log.info("原始URL: " + url);String timestamp = Long.toString(System.currentTimeMillis() / 1000);String nonceStr = getRandomStr(8);log.info("随机串:"+nonceStr+", 获取签名URL: " + url);JSONObject respJson = new JSONObject();String[] signArr = new String[]{"url=" + url, "jsapi_ticket=" + getWXJsapiTicket(), "noncestr=" + nonceStr, "timestamp=" + timestamp};Arrays.sort(signArr);String signStr = StringUtils.join(signArr, "&");String resSign = DigestUtils.sha1Hex(signStr);log.info("返回的签名:" + resSign);respJson.put("appId", appId);respJson.put("timestamp", timestamp);respJson.put("nonceStr", nonceStr);respJson.put("signature", resSign);log.info(respJson.toJSONString());return ResultData.success(respJson);}/*** 获取jsapi_ticket方法* @return*/private String getWXJsapiTicket() {String ticket = stringRedisBaseDao.getItem(appId);if (StringUtils.isBlank(ticket)) {String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + getWXaccessToken() + "&type=jsapi";String resp = restTemplate.getForObject(url, String.class);JSONObject resJson = JSONObject.parseObject(resp);log.info("获取到ticket:" + resJson.getString("ticket"));stringRedisBaseDao.addItem(appId, resJson.getString("ticket"), expireTime);return resJson.getString("ticket");}return ticket;}/*** 获取access_token* @return*/private String getWXaccessToken() {String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;String resp = restTemplate.getForObject(url, String.class);JSONObject resJson = JSONObject.parseObject(resp);log.info("获取到access_token:" + resp);return resJson.getString("access_token");}/*** 随机字符串* @param length* @return*/public static String getRandomStr(int length) {String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";int randomNum;char randomChar;Random random = new Random();// StringBuffer类型的可以append增加字符StringBuffer str = new StringBuffer();for (int i = 0; i < length; i++) {// 可生成[0,n)之间的整数,获得随机位置randomNum = random.nextInt(base.length());// 获得随机位置对应的字符randomChar = base.charAt(randomNum);// 组成一个随机字符串str.append(randomChar);}return str.toString();}}
微信分享步骤测试 建议在wechat开发工具中测试
配置 switchhost 将本机指向JS接口安全域名

本文使用 文章同步助手 同步