微信分享

公众号项目需要在页面中做分享控制,有的页面可以分享,有的不允许分享。具体的流程做个记录

基本原理是调用微信浏览器内置的对象进行控制。

步骤一:绑定域名

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

备注:登录后可在“开发者中心”查看对应的接口权限。

步骤二:引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js

备注:支持使用 AMD/CMD 标准模块加载方法加载

步骤三:通过config接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

var list = [ 'onMenuShareTimeline'          //分享到朋友圈
              ,'onMenuShareAppMessage'    //发送给好友
              , 'showMenuItems'           //显示功能按钮
              ,'hideAllNonBaseMenuItem'      //隐藏所有非基础功能按钮
           ];
wx.config({
            debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: param.appId, // 必填,公众号的唯一标识
            timestamp: param.timestamp, // 必填,生成签名的时间戳
            nonceStr: param.nonceStr, // 必填,生成签名的随机串
            signature: param.signature,// 必填,签名,见附录1
            jsApiList: list // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
        });

代码中的param由后台返回,appId,timestamp,nonceStr这三个参数容易获取,signature需要调用微信的接口拿到ticket,并按照微信规定的算法生成。(另:注意参数大小写)

signature的获取方法如下

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

其中grant_type固定为client_credential,appid为公众号ID,secret为公众号密钥。
会返回JSON格式数据。

{"access_token":"ACCESS_TOKEN","expires_in":7200}

做好本地缓存,如果参数未过期,不需要访问接口来获取参数,直接本地获取。

2.拿到jsapi_token

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

其中type固定为jsapi,access_token为上一步获取到的access_token
成功返回如下JSON:

{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}

同样ticket需要缓存到本地。
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

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

PHP代码示例如下

//获取sign
        $link = $_SERVER["HTTP_REFERER"];
        //1.获取ticket
        $ticket = $this->get_ticket();
        //2.按照ASCII码排序,生成字符串
        $arr = [];
        $arr["noncestr"] = $json["nonceStr"];
        $arr["jsapi_ticket"] = $ticket;
        $arr["timestamp"] = $now;
        $arr["url"] = $link;
        ksort($arr);
        $str = "";
        foreach($arr as $k=>$v) {
            $str .= $k;
            $str .= "=";
            $str .= $v;
            $str .= "&";
        }
        $str = rtrim($str, "&");
        $signature = sha1($str);

其中noncestr为生成的随机字符串,url为需要做分享的页面地址
最终生成的$signature就是签名字符串。
(另,此处的foreach循环不建议改用http_build_query函数,因为http_build_query会对数据urlencode,可能会碰到坑)

到此,wx.ready配置信息已经完成。之后调用wx.ready来控制分享功能

wx.ready(function () {
            //隐藏所有非功能按钮
            wx.hideAllNonBaseMenuItem();
            if(is_share) {
                var obj = {
                    title : title,                //分享标题
                    desc : desc,            //分享描述信息
                    link : param.link,    //进行分享的页面地址
                    imgUrl : imgUrl      //分享的logo图片
                };
                //显示分享给朋友、分享到朋友圈按钮
                wx.showMenuItems({
                    menuList: ['menuItem:share:appMessage', 'menuItem:share:timeline'] // 要显示的菜单项,所有menu项见附录3
                });
                // 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口
                wx.onMenuShareTimeline(obj);

                //监听“分享到好友”
                wx.onMenuShareAppMessage(obj);
            }
        });

此项目中只开启了分享给好友和分享到朋友圈。
参考微信JS-SDK说明文档
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

差点忘了,还有个坑,获取access_token的时候,需要在公众平台后台设置IP白名单,将你的服务器IP地址加进去,否则会报错。
欢迎批评指正,也欢迎大家留言交流。

你可能感兴趣的:(微信分享)