关于微信二次分享图标和标题丢失踩过的那些坑~

这篇文章讲的很全面: https://blog.csdn.net/u011225099/article/details/76460197

我主要记录下我自己踩的坑。

一、绑定安全域名

在微信公众平台—>公众号设置—>功能设置下面修改js安全域名。

坑1:安全域名不能带http://

域名不是url,不能携带协议部分,所以设置安全域名应该为去掉http://的部分,如果不行还需要将www.也去掉。另外,安全域名不能带端口号。

坑2:分享链接不在安全域名下

我的安全域名设置的xxxx.net,然后分享的页面因为是后端页面,所以携带了端口号,是xxxx.net:8848/index.html,导致分享失败。

这一步没做好,就会疯狂报 invalid url domain 的错。

绕过这两个坑,安全域名就没问题了,下一步就是页面。

二、页面获取签名

签名这块应该是后台处理,如果没处理好,就会报 invalid signature 的错误。

前端请求后台获取签名,需要携带当前页面路径作为参数,因为签名需要这部分参数

坑1:生成签名的参数要和分享之后的路径一样

生成签名时,需要分享路径作为参数,这个路径要和分享之后访问的路径一样,所以需要去掉微信增加的额外参数,即:

var href = location.href.split('#')[0]; //去掉分享后微信增加的路径参数

坑2:wx.config的参数遵循驼峰命名

如果是全干的小伙伴容易中招,因为后端生成签名的参数是全小写,而前端wx.config里面的参数又遵循驼峰命名规则

完整代码如下,详细步骤见注释:

var href = location.href.split('#')[0];
    $.getJson('/wxPublic/getSign?url=' + href, function (resp) {
        console.log(resp)
        wx.config({
            debug: true,  // 是否开启debug模式,如果开启,每次回调有内容会alert出信息
            appId: resp.appId, // 后端返回的公众平台appid
            timestamp: resp.timestamp, // 后端返回的时间戳
            nonceStr: resp.nonceStr, // 后端返回的随机字符串
            signature: resp.signature, // 后端返回的签名
            jsApiList: [    // 需要调用的jsApi
                'checkJsApi',
                'onMenuShareTimeline',//分享到朋友圈
                'onMenuShareAppMessage'//分享给微信好友
            ]
        });
        wx.ready(function () {
            wx.onMenuShareTimeline({ //分享到朋友圈
                title: shareTitle, // 分享标题
                link: href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                imgUrl: imgUrl, // 分享图标
                success: function () {
                    // 用户确认分享后执行的回调函数
                },
                cancel: function () {
                    // 用户取消分享后执行的回调函数
                    alert('你还没分享哦')
                }
            });
            wx.onMenuShareAppMessage({  // 分享给朋友
                title: shareTitle, // 分享标题
                desc: descContent, // 分享描述
                link: href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                imgUrl: imgUrl, // 分享图标
                type: '', // 分享类型,music、video或link,不填默认为link
                dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                success: function () {
                    // 用户确认分享后执行的回调函数
                },
                cancel: function () {
                    // 用户取消分享后执行的回调函数
                    alert('你还没分享哦')
                }
            });
        });
        wx.error(function (res) {
            // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
        });
    })

三、后端生成签名

接下来是后端接口获取签名的方式,全干的小伙伴可以看这边:

坑1:appid和appsecret都是微信公众平台的配置

个人在这里坑了最久,因为我这个项目使用了微信网站开放平台,微信app开放平台,一开始都用的那两个平台的appid和appsecret,结果一直提示 invalid url domain 。后来一步步检查才发现项目的公众平台的appsecret都还没申请。

坑2:生成签名要注意的问题

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

第二步,按照要求的规则进行计算签名,这里官方文档要求的是使用sha1加密,所以使用sha1加密获得签名。

这个坑主要报的错就是 invalid signature

完整代码如下,详细步骤见注释:

@GetMapping("/getSign")
    @ApiOperation("签名接口")
    public ResponseEntity appMsg(String url) throws Exception {
        // 时间戳,秒为单位
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        // appid,注意这里是微信公众平台的appid
        String appId="";
        // appsecret,注意这里是微信公众平台的appsecret
        String appsecret="";
        // 先获取accessToken,该token有2小时有效期,后续需要对该token做缓存
        String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token" +
            "?grant_type=client_credential" +
            "&appid=" + appid +
            "&secret=" + appsecret;
        String tokenInfoStr = HttpRequestUtil.httpGet(tokenUrl, null, null);
        accessToken = JsonPath.read(tokenInfoStr, "$.access_token");
        // 根据token获取jsApiTicket,该ticket有2小时有效期,后续需要对该ticket做缓存
        String jsApiUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket" +
            "?access_token="+accessToken+"&type=jsapi";
        String jsApiJson = HttpRequestUtil.httpGet(jsApiUrl, null, null);
        jsApiTicket = JsonPath.read(jsApiJson, "$.ticket");
        // 给前端的返回值
        Map<String, String> data = new HashMap<>();
        data.put("appId", appid);
        data.put("nonceStr", WXPayUtil.generateNonceStr());
        data.put("timestamp", timestamp);
        // 拼接字符串,使用sha1加密获得签名
        String params=
            "jsapi_ticket="+jsApiTicket+
            "&noncestr="+data.get("nonceStr")+
            "&timestamp="+timestamp+
            "&url="+url;
        String sign = DigestUtils.sha1Hex(params);
        data.put("signatrue", sign);
        return ResponseEntity.ok(data);
    }

版权声明:本文为Apoca_lypse原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。