前言
微信分享(使用微信JS-SDK)、微信JS-SDK是面向网页开发者提供的基于微信内的网页开发工具包。JSSDK使用官方文档(官方使用手册)
详解一下我的使用流程以及踩坑记录,我做的项目属于公众号h5项目,今天突然接到需求对主推的某两个页面自定义分享内容,之前做过微信小程序和支付小程序的分享,都是直接使用特定的API修改标题、描述、图片、链接,想着贼简单,预估工时共要了一天,一把辛酸泪~~
1、使用步骤
1)安装依赖包npm或yarn
npm i --save weixin-js-sdk
2)这里我在utils里面新建文件wechat.js代码如下:
import wx from 'weixin-js-sdk'
import {wxShare} from '@/api/wechat.js'
export default {
init (apiList = [],url) {
url = process.env.VUE_APP_API_GATEWAYS+url
let params={
appId:process.env.VUE_APP_API_APP_ID,
url:url
}
return new Promise((resolve, reject) => {
wxShare(params).then(res => {
if (res.code=="0000") {
wx.config({
debug: false,
appId: process.env.VUE_APP_API_APP_ID,
timestamp:res.data.timestamp,
nonceStr:res.data.nonceStr,
signature:res.data.signature,
jsApiList: apiList
})
wx.ready(() => {
resolve(wx)
})
wx.error(function (err) {
reject(err)
})
}
})
})
}
}
3)单个页面的分享自定义:在需要分享的页面mounted里面进行config签名,需要什么功能,签名时传入对应的jsApiList注册,签名ok后,ready中进行配置分享朋友、分享朋友圈等的title、desc、link、imgLink的配置。
先引入utils中的wechats.js
import utilWechat from '@/utils/wechat'
代码如下:
mounted() {
let title=document.title//当前页面的标题
let desc="这个是分享的描述信息"//自己配置的描述信息
let link=process.env.VUE_APP_API_GATEWAYS+this.url//分享的链接
let imgUrl =process.env.VUE_APP_API_GATEWAYS+'/automic.png'//分享的图片链接
// let link=location.protocol+'//'+location.host+this.url//这种获取路由方式也行
// let imgUrl =location.protocol+'//'+location.host+'/'+'automic.png'//同上
//api列表、这里我把文档里面新版的分享朋友和分享朋友圈api也注册进去了,因为不知道使用新版还是旧版,经过测试还是旧版的好用,如果使用新版的,可按官方手册和社区大家的案例来,避免踩坑
let APILIST=["onMenuShareTimeline","onMenuShareAppMessage",'updateTimelineShareData','updateAppMessageShareData']
utilWechat.init(APILIST,this.url).then(wx => {
wx.onMenuShareAppMessage({
title,
desc,
link,
imgUrl,
success: function () {
alert(`分享成功`);
},
cancel: function () {
alert(`取消分享`);
}
});
wx.onMenuShareTimeline({
title,
desc,
link,
imgUrl,
success: function () {
alert(`分享成功`);
},
cancel: function () {
alert(`取消分享`);
}
});
//新版本分享(ready外面)
// wx.updateAppMessageShareData({})
// wx.updateTimelineShareData({})
});
},
4)因为我这里不是要求全部页面都需要自定义分享,所以我在项目中方便省事就没封装传参title、描述、等。如果每个页面都需要自定义分享,可以给每个路由配置对应的自定义信息设置在meta中,动态读取、获取签名、动态配置页面的自定义参数。
2、踩坑注意点来喽
1)页面分享出来只有一个链接
h5微信项目、通常我们在微信会话中通过链接也可以直接进入公众号网页、和通过公众号菜单跳转进入没什么区别,没毛病。
因为测试公众号菜单暂时挂的是灰度环境,测试环境只能通过链接进入,测试页面自定义分享后,我蒙了,就只有一个链接,why?点击链接进入页面右上角分享给朋友后,直接分享出去了一个链接,没有做过,毫无经验,以为自己的代码有什么毛病,微信开发者工具中测试config:ok,登录微信公众号后台,也配置了js安全域名,根本无头绪。
查看了一些资料后无果,最后再社区里面找到同样问题:公众号页面分享出来只有一个链接?
读后来来回回测试了几遍,结论:
1.微信会话的链接收藏后,通过收藏链接后再从我的收藏中打开再去分享是正常的
2.链接换成二维码 扫码后进入分享是正常的
3.直接通过微信公众号菜单点击进去分享页面是正常的
2)安卓正常、IOS分享自定义配置无效问题
我是安卓手机,明白了第一个问题是微信官方的规则后,通过结论测试微信分享后恢复正常,发版到测试环境后,出现ios手机分享出来的卡片配置的标题、描述等无效。
又查了很多资料,
1.排除图片不能超过33k问题,
2.排除配置的link里面不能有特殊字符需对特殊字符进行编码,使用 encodeURIComponent() 问题
3.排除直接通过location.protocol+'//'+location.host+...来设置link
4.排除hash路由截取#前面作为拼接(项目使用的是history)
这些问题排除后,在手机上突然灵机一动想着刷新一下别是缓存问题代码发版无效,然后点击分享,my god,居然正常了,反复测试了几遍,排除了缓存问题,第一次分享确实无效,但是经过刷新页面再去分享,正常了。
怀疑是ios签名和安卓是不是有什么差异,开始继续查找资料,找到遇到同样问题的前端伙伴,不过他使用的是hash路由也就是说,不可沿用此方法,但是得到结论ios确实签名和安卓有不一样地方,只是迷惑使用当前路由去获取签名没错,官方就是这样说的。
尝试在签名之前alert出来了url进行对比,看到安卓和IOS的url都是当前页面,抑郁了。。。。。。。此处省略一万字
3)可以确定是ios的签名错误的问题了,Ios第一次签名config:invalid signature,刷新页面后config:ok
所以可能的情况全部排查了,均不是,最后发现了IOS的路由机制和安卓不同。
我需要分享的页面是进入网页后二次跳转的页面,所以路由变化了
虽然我分享前alert的是当前页面的路由(跳转后最新的url)去签名,但是签名失败。
经测试如果不跳转页面,ios分享是有效的,跳转的时候更改了页面的url:
问题出在:
ios系统对vue的history路由的支持上,由于Vue的单页面应用,我alert出来的虽然是我所要的当前页面url,只要不刷新页面,ios获取到的url还是进入网页的第一个url(我的home页),这样请求签名就会变成动态url不一致的问题才导致签名失败。
解决办法:
在路由守卫中首先判断安卓、IOS,如果是安卓每次都拿当前页面地址进行签名就行,如果是IOS机型,路由守卫中保存首次进入时的url,路由进入页面时判断当前页面url和首次进入的链接地址是否一致,如果不一致用location.replace刷新页面,拿刷新后的url进行签名。
具体代码如下:
//此处只写了核心代码,根据需求往里面插入代码就行
router.beforeEach((to, from, next) => {
let link=process.env.VUE_APP_API_GATEWAYS+to.fullPath//当前页面的url
//判断是否是苹果手机
var ua = navigator.userAgent.toLowerCase();
let newValue = ua.indexOf('iphone')
if(newValue != -1){ //苹果手机做判断
if (window.entryUrl === '' || window.entryUrl === undefined || window.entryUrl === null) {
window.entryUrl = link
}
//入口url与当前需要签名的url不一致,赋值,刷新页面重新签名
if (window.entryUrl !== link) {
window.entryUrl = link
window.location.replace(link)
}
}else{
next()
}
})
4)发版到测试环境测试过后,分享配置一切正常,这里做下踩坑记录,代码不多,没做过这块的真的是得一点一点试探呀,孩子太难了,魔怔了,不过解决了很开心!