使用微信js-sdk自定义分享

4,160 阅读5分钟

微信二次分享展示优化

原有的H5项目在微信分享后展示的只有缩略图和展示链接,影响了文章的二次传播效果;

查看官方文档后了解到可以用微信的jssdk:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115;

一. JSSDK使用步骤

  • 1.1 绑定域名

  先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”,可以按照提示进行填写,最多填写三个。

  登录后可在“开发者中心”查看对应的接口权限,只有获取了权限才能保证后面的工作继续进行。

  • 1.2 引入JS文件

     在需要调用JS接口的页面引入如下JS文件,(支持https):res.wx.qq.com/open/js/jwe… 支持使用 AMD/CMD 标准模块加载方法加载; 请注意,原有的 wx.onMenuShareTimeline、wx.onMenuShareAppMessage、wx.onMenuShareQQ、wx.onMenuShareQZone 接口,即将废弃。请尽快迁移使用客户端6.7.2及JSSDK 1.4.0以上版本支持的 wx.updateAppMessageShareData、updateTimelineShareData 接口。 实际测试中发现在客户端6.7.2以下的版本中wx.updateAppMessageShareData、updateTimelineShareData 方法无法正常调起;为了兼容老的客户端我使用的是wx.onMenuShareTimeline、wx.onMenuShareAppMessage、wx.onMenuShareQQ、wx.onMenuShareQZone 接口

  • 1.3 通过config接口注入权限验证配置

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

/* 获取微信的sdk (获取微信授权域名); wx.config配置项如下;
* @param {Boolean} debug   开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
* @param {String}  appId   必填,公众号的唯一标识
* @param {String}  timestamp   必填,生成签名的时间戳
* @param {String}  nonceStr    必填,生成签名的随机串
* @param {String}  signature   必填,签名
* @param {Array}   jsApiList   必填,需要调用的JS接口列表
*/
export function getWechatSdk() {
    const url = location.href;
    apiPost('getWeiXinSign', { url }, 'wx').then(response =>{
        const res = response.data;
        wx.config({
            debug: false,              
            appId: res.appId,         
            timestamp: res.timestamp,
            nonceStr: res.nonceStr,
            signature: res.signature, 
            jsApiList: [
                'onMenuShareTimeline',
                'onMenuShareAppMessage',
                'onMenuShareQQ',
                'onMenuShareWeibo',
                'onMenuShareQZone'
            ]
        });
    });
}
  • 1.4 通过ready接口处理成功验证;

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

/* 微信分享的方法;
* @param {String}  title     分享标题;
* @param {String}  link      分享链接;(location.href)
* @param {String}  imgUrl    分享图标;(取后台字段, 没有返回时默认取第一张图片)
* @param {String}  desc      分享描述;(取后台字段, 没有返回时采用产品定义的描述文案)
* @return {Object} success   确认分享后执行的回调;
* @return {Object} cancel    取消分享后执行的回调;
*/
export function wechatShare(title, link, imgUrl, desc) {
    wx.ready(function(){
        // 自定义“分享到朋友圈”
        wx.onMenuShareTimeline({
            title: title,  
            link: link,        
            imgUrl: imgUrl,
            success: function () {},
            cancel: function () {}
        });
        // 自定义“分享到QQ空间”
        wx.onMenuShareQZone({
            title: title,
            desc: desc,
            link: link,
            imgUrl: imgUrl,
            success: function () {},
            cancel: function () {}
        });
        // 自定义“分享给微信好友”
        wx.onMenuShareAppMessage({
            title: title,
            desc: desc,
            link: link,
            imgUrl: imgUrl,
            success: function () {},
            cancel: function () {}
        });
        // 自定义分享给QQ好友”
        wx.onMenuShareQQ({
            title: title,
            desc: desc,
            link: link,
            imgUrl: imgUrl,
            success: function () {},
            cancel: function () {}
        });
    })
}

完成以上步骤后,在微信客户端就可以正常发起自定义分享了;

二. Webapp下使用的情况;

  • 按照之前的套路继续优化一个react开发是spa的webapp;发现不能实现以上的效果;

  • IOS下遇到了问题:

      打开页面时分享没有问题,路由跳转一次之后再分享签名错误(invalid signature)
    

    这个问题是由于IOS微信浏览器下,有着下面的“特性”:

    把第一次打开的页面叫做进入页;把前端路由若干次跳转(通过pushState/replaceState改变url)之后,当前打开的页面叫做当前页。 举例在http://xxx.xxx.com/wx/index.html?#/product?id=1; 微信验签使用的url(当前网页的URL,不包含#及其后面部分),在Android下取的是当前页url,在IOS下取的是进入页的url(支付目录也是一样) 这是就会造成签名失败;

  • Android下遇到了问题:

    是在苹果手机的微信上面,只要调用 wx.config 一次就可以了,但是在 android 的手机,在页面跳转之后,wx.config(url 依然是进入网站的第一个页面的地址,要保存在一个变量里面);

    解决思路: 项目中用了 react-router(3.x版本, 4.x的没有测试) ,直接在 Route 组件上绑定一个 onEnter 方法;

const enterTab = () => {
    if (isWechat()) getWechatSdk();
};
export default (
    <Route path="/" component={App}>
        <IndexRoute getComponent={xxx} />
        <Route path="product" getComponent={Product} onEnter={enterTab.bind(this)} />
    </Route>
);
export function getWechatSdk() {
    // 拿到微信授权域名http://xxx.xxx.com/wx/index.html进行签名验证;
    const url = window.location.href.split('#')[0]; 
    callApi('getWeiXinSign', { url }).then(res =>{
        wx.config({
            debug: false,              
            appId: res.appId,         
            timestamp: res.timestamp,
            nonceStr: res.nonceStr,
            signature: res.signature, 
            jsApiList: [
                'onMenuShareTimeline',
                'onMenuShareAppMessage',
                'onMenuShareQQ',
                'onMenuShareWeibo',
                'onMenuShareQZone'
            ]
        });
    });
}

完成以上步骤后,在微信客户端spa也可以正常发起自定义分享了;

测试的react的spa,VUE没有测试,单原理应该是相通的,不对之处欢迎批评指正

过程中参考了下面的文章;