在微信浏览器中自定义分享的页面的描述信息

在微信浏览器中自定义分享的页面的描述信息

zeee 1,574 2019-11-03

这是微信公众号专属权利, 如果没有微信开发接口的话正常的分享只能使用默认的分型信息

需求描述

在开发移动端的页面时,有分享到微信朋友圈的需求。比如:
IMG_20191024_224618

但是如果没有额外设置的话,微信默认分享的样式只是默认获取网页的标题,而且不会自动获取图片,像这样:

IMG_20191024_224327

首先,这就过不了产品这一关, 其次呢, 没有其次。所以我们下一个需求就是,让分享到朋友圈或者微信朋友的页面可以自定义标题, 图片和描述信息。

食材准备

查了一下微信的文档, 我们找到这么一条自定义“分享给朋友”及“分享到QQ”按钮的分享内容(1.4.0), 是目前版本的微信所支持的, 所以按照这个思路做下去应该就可以实现了。

按照文档的说明, 这个接口是微信的JS-SDK实现的, 而要接入这个 SDK 呢需要做如下工作:

文档: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#0

  1. 绑定域名
  2. 引入js文件
  3. 通过config接口注入权限验证设置
  4. reeady接口中调用需要自动调用的 SDK 接口(因为 config 验证通过后会执行 ready,自动的借口只有在这里才能保证顺序正确)
  5. error借口中处理失败情况

大概是以上几个流程,其中第三步验证是异步的, 所以自动的方法需要用第四步来执行以保证顺序,当让如果是用户触发的操作的话就不需要(因为这个时候cofing接口已经验证完成)。有一丢丢类似于 ajax 。

其中第三步是最关关键的一环。 需要配置信息如下:

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

然后微信扔下一句话:

签名算法见文末的附录1,所有JS接口列表见文末的附录2

跑掉了。

稍微查了一遍文档,发现其中这个签名,是需要access_token来生成的, access_token 又是通过 appidsecret 来获取的。 那既如此, 只能通过后台来完成了, 不然把这个全部暴露在前端, 可就想前阵子闹的挺欢的某考试信息网了。

这样子事情明朗了:

  1. 绑定好域名
  2. 后端写一个接口, 返回计算好的接口,部署在第一步的域名下面
  3. 前端按照上面步骤接入, 从后端请求签名信息
  4. 位置自定义分享页面的内容。
  5. 监听分享事件,自动跳到朋友圈页面(划掉) 让用户自己点击右上角分享, 此时发现分享的链接会按照定要好的内容走起来 (这一点需要留意, 微信为了“不要有诱导分享等违规行为”,现在这样子, 不能在网页内弄一个分享按钮直接跳转)

上菜

这个问题难道我是第一个遇到的么? 不可能!

本着绝不重复造轮子的原则,我在某hub上疯狂搜索,发现果不其然已经有人做了相当不错的东西,只需要拿过来用就是了:

  1. imokya/wechat-share : 基本包括了上面步骤中前端的工作, 这样一来只需要在后端写好借口就可以了, 而且接口设计特别简洁, 只需要提供接口地址就可以了, 美中不足的是后台借口的返回内容和实现方法没有给介绍, 所以一开始看的时候有点懵。
  2. backToNature/m-share: (非必选), 页面渲染部分, 可以省去许多画UI的工作,同时适配了几个浏览器的native分享。 事实上这个项目可以包含上面项目的内容, 不过对微信的借口设计没有那么简洁,两个配合使用更佳。

然后就是后端的问题,需要实现一个计算好签名的接口。 实现的算法在微信文档中国有介绍,基本上就是拿个时间戳,随机数怎么的组一组,然后加个密返回。 我们依旧首先不造轮子, 找一找其他人的实现:

这样一来, 我们只需把轮子组装起来,用简单几行代码就可以实现微信的自定义分享内容了, 前端代码大概长这样子:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>分享测试</title>
</head>
<body>
   <div id="share-wrapper"></div>
</body>
<script src="m-share.min.js"></script>
<script src="wechat.share.js"></script>
<script>
    const sharedata = {
        link: location.href, //分享链接
        title: '这是自定义分享的标题', //分享title
        desc: '这是分享的内容balababalabalaaaaaaaaaaaaaaaaa', //分享文案
        imgUrl: 'https://oldzengblog.oss-cn-beijing.aliyuncs.com/16274628_1568551424059.jpg',
    }
    const config = {
        apiURL: 'https://example.com/myapi', // 分享接口服务器地址, 返回jssdk签名, 与微信公众号配置中的域名一致
        wxURL: '//res2.wx.qq.com/open/js/jweixin-1.4.0.js', //JSAPI地址
        debug: false, //调试模式
        type: 'post', //请求类型
        jsonp: true, //jsonp跨域
        data: sharedata
    }
    new WechatShare(config)
    if(isWeixinBrowser)  // 如果是微信浏览器只显示分享到微信的按钮(可忽略这一段)
        sharedata.types =  ['wx', 'wxline']
    Mshare.render('#share-wrapper', sharedata);

    function isWeixinBrowser() {
        navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == "micromessenger"
    }
</script>
</html>

端实现-泪的教训

关于后端的的实现, 重新部署过一次, 然而又踩了一次坑, 有些事情必须要说清楚:

  1. apiURL 所域名, 必须与公众号后台 微信公众平台-开发-基本配置-JS安全域名一致,比如api写https://www.x.com/xxx, 而安全域名填x.com就是不行的, 应该填www.x.com

  2. 必须将后端借口所部署的服务器的IP地址加入到微信公众平台-开发-基本配置-IP白名单中, 否则无法调用成功, 拿不到 access_token

  3. 后端实现的接口应该是返回类似下面这样的结构.

    {
        "appId": "wxxxxxxxxxxx",
        "timestamp": 1586626880,
        "nonceStr": "xxxxxxxxx",
        "signature": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "url": "https:\/\/example.com\/xxx.htm"
    }
    
  4. (接3) 但是!!! PHP 有可能会很鬼畜!!! 它可能需要返回这样的格式: CallbackFunction({....}) 里面才是真正的json , 而如果直接返回JSON的话会报语法错误: Uncaught SyntaxError: Unexpected token ':'. 这个CallbackFunction应该是请求Url中的callback参数的值, 如果没有这个参数, 它可能要直接返回json吧. 参考链接

最终实现效果:

1572056771916

👇

1572056628837


# wechat