微信分享

微信分享功能

该文章大部分取自官方文档,加以自己的理解整理记录。

因为刚使用所以遇到很多不懂的地方,网上查了很多资料,大多数和官方文档差不多,忽略了很多细节,这对刚刚接触微信公众号开发的我带来不少麻烦,所以在这里记录一下自己的使用过程,遇到哪些问题,是怎么解决的,希望对小白有用。

微信JS-SDK说明文档

分享功能是在微信内置浏览器中才能使用的功能,暂不知道怎么在PC上使用,如有知道,请不吝赐教。

本来使用JiaThis做PC端的微信分享的功能,但是后来分享业务被砍掉了,所以改为微信公众平台做分享功能。

由于JS-SDK只能在微信内置浏览器使用,所以不能在PC上直接做分享功能,解决思路是在PC上生成一个二维码地址,用微信扫一扫跳到这个地址,然后分享。

1. 绑定域名

只有绑定成功的域名才能调用对应微信公众号接口。

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

这里写图片描述
这里写图片描述

这里有两点须有注意,在绑定域名的时候需要将指定的.txt文件下载后放到填写域名或路径指向的web服务器(或虚拟主机)的目录。

1.1 域名的填写

例如想绑定的域名为http://wxainn.com,那么输入框里填写http://后面的部分,wxainn.com

1.2 指定.txt文件的放置

假如.txt的文件名为wx.txt

无论服务器怎样配置,只要在浏览器里输入http://wxainn.com/wx.txt能够访问到就可以,否则点击保存的时候会提示以下信息。
这里写图片描述

因为我的服务器80端口已经用部署了应用程序,所以只需要将wx.txt放到/webapps/ROOT目录下。当浏览器输入http://wxainn.com/wx.txt时能够访问到该文件。

2. 引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):

http://res.wx.qq.com/open/js/jweixin-1.2.0.js

比如这样:

<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript"></script>

3. 通过config接口注入权限验证配置

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

我这里使用Java作为后台开发语言,将这些参数写在application.properties文件里,在后台计算好需要参数返回给前台使用。

3.1 四个重要参数讲解

下面说一下每个参数怎么计算得出:

3.1.1 appId:公众号的唯一标识,直接读取配置文件。

这里写图片描述

3.1.2 timestamp:当前时间戳(单位:秒)。

计算很简单:

public static String getTimeStamp() {
    return String.valueOf(System.currentTimeMillis() / 1000);
}
3.1.2 nonceStr:生成签名的随机串
public static String getNonceStr() {
    Random random = new Random();
    return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)), "UTF-8");
}
3.1.4 signature:签名

这4个参数,签名计算最麻烦。签名就是根据包括appIdtimestampnonceStr和其它一些参数计算得出的。所以这里计算签名所用到的参数,和传到前台的必须一一对应,否则前台验证不通过。下面说一下怎么计算签名。

3.1.4.1 获取access_token

官方文档说的很详细,点击标题可以查看。

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_tokenaccess_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

接口调用请求说明:

https请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

appid:第三方用户唯一凭证,即上文的appid
secret:第三方用户唯一凭证密钥,即appsecret
这里写图片描述

简单描述获取流程:

  1. 获取自己的appidsecret
  2. 后台定时任务,每隔一个小时获取一次access_token
  3. 拼接请求url,get方式请求,将返回json值解析出access_token,存在Redis中。
3.1.4.2 jsapi_ticket

生成签名之前必须先了解一下jsapi_ticketjsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket

接口调用请求说明:

https请求方式: GET
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

只有一个参数ACCESS_TOKEN,就是上一步获取到的access_token

简单描述获取流程:

  1. 和获取access_token写在一个定时任务中,获取完access_token紧接着获取jsapi_ticket
  2. 拼接请求url,get方式请求,将返回json值解析出ticket,存在Redis中。

获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

3.1.4.3 计算signature

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

文档说了一大堆,其实就简单拼接一个字符串作sha1加密就可以,字符串格式如下:

jsapi_ticket=JSAPI_TICKET&noncestr=NONCESTR&timestamp=TIMESTAMP&url=URL

参数顺序不能变。
为了便于区分参数和值,参数小写,值大写。

  • jsapi_ticket:前面获取的jsapi_ticket
  • noncestr:前面提到的随机串。
  • timestamp:前面提到的时间戳。
  • url:当前网页的URL,不包含#及其后面部分。

这里要注意url,不包含#及其后面部分并且不能对url进行转义。格式如下:

http://mp.weixin.qq.com?params=value

拼接好字符串string1进行sha1加密即可,加密后得到的字符串就是签名signature。

这里我们服务器后台计算签名后传到前台页面,微信会根据参数noncestrtimestamp和当前url,公众号里的appidappsecret再次进行计算签名,如果两次不一致,则不允许调用接口。

调试的时候可以用下面的小工具,检查自己计算的签名是否正确:

微信 JS 接口签名校验工具:
这里写图片描述

4. 通过ready接口处理成功验证

config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

wx.ready(function(){
    // 
});

5. 通过error接口处理失败验证

config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。

wx.error(function(res){
    // 
});

6. 获取“分享给朋友”按钮点击状态及自定义分享内容接口(即将废弃)

wx.onMenuShareAppMessage({
    title: '', // 分享标题
    desc: '', // 分享描述
    link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
    imgUrl: '', // 分享图标
    type: '', // 分享类型,music、video或link,不填默认为link
    dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
    success: function () {
    // 用户点击了分享后执行的回调函数
    }
});

7. 前台页面

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ include file="../../common/taglib.jsp" %>
<html>
<head>
    <meta charset="UTF-8">
    <title>邀请注册-超级人才</title>
    <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta name="format-detection" content="telephone=no">
    <meta name="msapplication-tap-highlight" content="no">

    <meta name="theme-color" content="#4e8ef7">

    <!-- add to homescreen for ios -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
</head>
<body style="padding: 0;margin: 0; min-width: 300px; min-height: 500px">


<iframe src="${webUrl}" style="border: 0; margin: 0;padding: 0; height: 100%;width: 100%"></iframe>

<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript"></script>
<script>

    // alert("点击分享,发送给朋友");

    wx.config({
        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '${appId}', // 必填,公众号的唯一标识
        timestamp: '${timestamp}', // 必填,生成签名的时间戳
        nonceStr: '${nonceStr}', // 必填,生成签名的随机串
        signature: '${signature}',// 必填,签名
        jsApiList: ['onMenuShareAppMessage', 'hideMenuItems'] // 必填,需要使用的JS接口列表
    });
    wx.ready(function () {
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
        wx.hideMenuItems({
            menuList: [
                'menuItem:share:timeline',//分享到朋友圈: "menuItem:share:timeline"
                'menuItem:share:qq',//分享到QQ
                'menuItem:share:weiboApp',//分享到Weibo
                'menuItem:favorite',//收藏
                'menuItem:share:facebook',//分享到FB
                'menuItem:share:QZone'//分享到 QQ 空间
            ] // 要隐藏的菜单项,只能隐藏“传播类”和“保护类”按钮,所有menu项见附录3
        });
        wx.onMenuShareAppMessage({
            title: '${welTitle}', // 分享标题
            desc: '${welSummary}', // 分享描述
            link: '${webUrl}', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            imgUrl: '${welPic}', // 分享图标
            type: 'link', // 分享类型,music、video或link,不填默认为link
            dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
            success: function () {
                // 用户点击了分享后执行的回调函数
                //关闭当前网页
                wx.closeWindow();
            }
        });
    });
    wx.error(function(res){
        // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
        alert(res)
    });
</script>
</body>
</html>

8. 成果

PC端页面,点击微信分享弹出二维码:
这里写图片描述

微信扫一扫后分享:
这里写图片描述

这里写图片描述

这里写图片描述

9. 错误记录

测试的时候遇到很多问题,现简单列举几个,如果遇到类似问题,也许对你有帮助:

  1. 前台验签失败。原因是计算签名用的timestampnoncestr和传到前台的不一致。
  2. 前台验签失败。原因是计算签名的时候url路径写错,没有写param=value部分,即?之后的部分。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值