需求场景
需求是要开发一个H5,用户通过扫描二维码进入页面,然后可以对页面分享到朋友圈或者好友。
划重点!!!
H5可以在微信中分享为卡片形式,需要满足以下条件之一:
- 需要绑定微信公众号【必须有一个经过认证的微信公众号,个人公众号无法实现此功能】;
- H5需要通过二维码扫码进入;
- H5需要从绑定的公众号中的菜单里点击进入;
- H5本身在微信中就是卡片形式,点击后再分享依然还是可以通过卡片形式分享出去;
1、配置公众号
1.1 设置JS接口安全域名
首先需要把验证文件下载下来,放到项目的根目录下,比如前端使用**vue**写的,你就放在**public**文件夹下,部署到服务器后,通过地址 www.test.com/***verify.txt 可以访问到文件及内容即可。
然后把H5的域名配置上去:比如 **www.test.com** ,这里无需添加协议。业务域名如果有坑位,也设置上比较好,不是必须。在配置域名的时候,微信会通过你配置的域名访问校验文件,访问通过后,即可配置成功。
1.2 配置IP白名单
获取到服务端的ip地址,将**服务端的IP**地址配置到下方的**IP白名单**中,服务端就有权限拿公众号的AppId和AppSecret两个密钥去获取access_token,从而可以生成前端所需要的wx。config中的参数(包含签名、时间戳、随机字符串等参数)
(注意:这里的服务器配置建议开启,有文章说这里必须设置,但小编这次没有设置也成功分享成卡片形式了,因为小编使用的公众号已经设置了别的域名,此时没有办法添加新的域名。)
1.3检查公众号是否已经获取相对应的权限
在设置与开发中的接口权限中,检查公众号是否开通对应所需要的接口权限。
以上就配置完成公众号了,可以进入编码阶段。
2、生成签名
2.1获取access_token
参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
2.2获取jsapi_ticket
用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
成功返回如下JSON:
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
2.3服务端签名算法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
即signature=sha1(string1)。 示例:
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value
步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步骤2. 对string1进行sha1签名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
注意事项
签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
签名用的url必须是调用JS接口页面的完整URL。
出于安全考虑,开发者必须在服务器端实现签名的逻辑。
如出现invalid signature 等错误详见附录5常见错误及解决办法。
3.前端微信分享功能实现
参考文档:微信开发者文档
3.1初始化微信配置
// 引入依赖方法一:使用 npm install weixin-js-sdk,安装weixin-js-sdk依赖包并引入
import wx from "weixin-js-sdk";
// 引入依赖方法二:在index.html引入下面的js文件
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
onMounted(()=>{
initWX()
})
initWX() {
// 为了使用微信JS-SDK,你需要先通过AppID和AppSecret从微信服务器获取Access Token,然后再用Access Token换取JSAPI Ticket。这一步通常在你的服务器端完成,因为AppSecret不应暴露在前端,该算法参考https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
const resData = await axios.post('/wx/get/signature')
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: resData.appId, // 必填,公众号的唯一标识
timestamp: resData.timestamp, // 必填,生成签名的时间戳
nonceStr: resData.noncestr, // 必填,生成签名的随机串
signature: resData.signature,// 必填,签名
jsApiList: [
'chooseImage',
'updateAppMessageShareData',
'updateTimelineShareData',
'onMenuShareAppMessage', // 旧的接口,即将废弃(网上说是要把旧接口也填上去,不然注册会失败)
'onMenuShareTimeline', // 旧的接口,即将废弃
] // 必填,需要使用的JS接口列表
});
wx.ready(function () { //需在用户可能点击分享按钮前就先调用
const params = {
title: 'H5标题', // 分享标题
link: location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: 'https://logo-aaeeeaca.png', // 分享图标,卡片右侧的图标
}
wx.updateTimelineShareData({
...params,
success: function () {
// 设置成功
console.log('updateTimelineShareData 朋友圈 success==>')
}
});
wx.updateAppMessageShareData({
...params,
desc:"",
success: function () {
// 设置成功
console.log('onMenuShareTimeline 朋友圈 success==>')
}
})
});
wx.error(function (res) {
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
console.log("验证失败返回的信息:", res);
location.reload()
});
}
3.2Api校验
确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。
3.3 常见问题
- 1、debug模式打开后, 页面打开没有任何提示。 这里检查下jssdk是否正确引入。config代码是否执行
- 2、wx.ready 方法不执行。这里重点检查下config方法是否执行
- 3、弹出提示签名错误,这里主要检查appid,和secrekey是否正确。可以使用 官方签名工具来验证签名是否正确
- 4、所有配置都正确但是提示授权失败,这里需要检查公众号性质。个人注册的公众号没有也无法获取分享功能接口使用的。在设置开发-接口权限那里可以看到
- 5、链接发送出去后是链接形式,不是卡片形式。这是由于微信要求链接只能通过公众号菜单分享,或者将链接生成二维码,用户扫码后再分享,这两种情况下分享出去才是卡片。
其实,问题就是官方在不久之前更新了分享机制…所以这个方法只是"预设分享文案",并不是触动分享功能