每回遇到微信分享都是一个坑,目前的商城项目使用 Vue 开发,采用 history 的路由模式,配置微信分享又遇到了很多问题,最后终于解决了,现将解决的过程分享一下。
原文 http://justyeh.top/post/39
技术要点
Vue,history
常见问题及说明
debug 模式下报 false
这个没得说,就是调用 wx.config 方法的参数错误造成的,请确认以下事项:
是否成功绑定了域名(域名校验文件要能被访问到)
使用最新的 js-sdk 文件,因为微信会改部分 api
config 方法的参数是否传正确了(拼写错误、大小写 …)
需要使用的方法是否写在了 jsApiList 中
获取签名的 url 需要 decodeURIComponent
后台的生成签名的加密方法需要对照官方文档
debug 返回 ok,分享不成功
确保代码拼写正确
分享链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致
接口调用需要放在 wx.ready 方法中
单页项目(SPA)中的一些要点
所有需要使用 JS-SDK 的页面必须先注入配置信息,否则将无法调用(同一个 url 仅需调用一次,对于变化 url 的 SPA 的 web app 可在每次 url 变化时进行调用, 目前 Android 微信客户端不支持 pushState 的 H5 新特性,所以使用 pushState 来实现 web app 的页面会导致签名失败,此问题会在 Android6.2 中修复)。
上面那段话摘自官方文档
开发者需要注意的事项:
android 和 ios 需要分开处理
需要在页面 url 变化的时候重新调用 wx.config 方法,android 获取签名的 url 就传 window.location.href
Vue 项目在切换页面时,IOS 中浏览器的 url 并不会改变,依旧是第一次进入页面的地址,所以 IOS 获取签名的 url 需要传第一次进入的页面 url
Code
router/index.js
……
import {wechatAuth} from “@/common/wechatConfig.js”;
……
const router = new Router({
mode: “history”,
base: process.env.BASE_URL,
routes: [
{
path: “/”,
name: “home”,
meta: {
title: “ 首页 ”,
showTabbar: true,
allowShare: true
},
},
{
path: “/cart”,
name: “cart”,
meta: {
title: “ 购物车 ”,
showTabbar: true
},
component: () => import(“./views/cart/index.vue”)
}
……
]
});
router.afterEach((to, from) => {
let authUrl = `${window.location.origin}${to.fullPath}`;
let allowShare = !!to.meta.allowShare;
if (!!window.__wxjs_is_wkwebview) {// IOS
if (window.entryUrl == “” || window.entryUrl == undefined) {
window.entryUrl = authUrl; // 将后面的参数去除
}
wechatAuth(authUrl, “ios”, allowShare);
} else {
// 安卓
setTimeout(function () {
wechatAuth(authUrl, “android”, allowShare);
}, 500);
}
});
代码要点:
meta 中的 allowShare 用于判断页面是否可分享
window.__wxjs_is_wkwebview 可用来判断是否是微信 IOS 浏览器
entryUrl 是项目第一次进入的页面的地址,将其缓存在 window 对象上
为什么安卓的时候要增加一个延时器,因为安卓会存在一些情况,就是即便签名成功,但是还是会唤不起功能,这个貌似是一个比较稳妥的解决办法
wechatConfig.js
import http from “../api/http”;
import store from “../store/store”;
export const wechatAuth = async (authUrl, device, allowShare) => {
let shareConfig = {
title: “xx 一站式服务平台 ”,
desc: “xxxx”,
link: allowShare ? authUrl : window.location.origin,
imgUrl: window.location.origin + “/share.png”
};
let authRes = await http.get(“/pfront/wxauth/jsconfig”, {
params: {
url: decodeURIComponent(device == “ios” ? window.entryUrl : authUrl)
}
});
if (authRes && authRes.code == 101) {
wx.config({
//debug: true,
appId: authRes.data.appId,
timestamp: authRes.data.timestamp,
nonceStr: authRes.data.nonceStr,
signature: authRes.data.signature,
jsApiList: [“updateAppMessageShareData”, “updateTimelineShareData”, “onMenuShareAppMessage”, “onMenuShareTimeline”]
});
wx.ready(() => {
wx.updateAppMessageShareData({
title: shareConfig.title,
desc: shareConfig.desc,
link: shareConfig.link,
imgUrl: shareConfig.imgUrl,
success: function () {
shareSuccessCallback();
}
});
wx.updateTimelineShareData({
title: shareConfig.title,
link: shareConfig.link,
imgUrl: shareConfig.imgUrl,
success: function () {
shareSuccessCallback();
}
});
wx.onMenuShareTimeline({
title: shareConfig.title,
link: shareConfig.link,
imgUrl: shareConfig.imgUrl,
success: function () {
shareSuccessCallback();
}
});
wx.onMenuShareAppMessage({
title: shareConfig.title,
desc: shareConfig.desc,
link: shareConfig.link,
imgUrl: shareConfig.imgUrl,
success: function () {
shareSuccessCallback();
}
});
});
}
};
function shareSuccessCallback() {
if (!store.state.user.uid) {
return false;
}
store.state.cs.stream({
eid: “share”,
tpc: “all”,
data: {
uid: store.state.user.uid,
truename: store.state.user.truename || “”
}
});
http.get(“/pfront/member/share_score”, {
params: {
uid: store.state.user.uid
}
});
}
总结
原先计划不能分享的页面就使用 hideMenuItems 方法隐藏掉相关按钮,在 ios 下试了一下,有些 bug:显示按钮的页面切换的影藏按钮的页面,分享按钮有时依然存在,刷新就没问题,估计又是一个深坑,没精力在折腾了,就改为隐私页面分享到首页,公共页面分享原地址,如果有什么好的解决办法,请联系我!
一开始我有参考 sf 上的一篇博客 https://segmentfault.com/a/1190000014455713,按照上面的代码,android 手机都能成功,但是 IOS 有一个奇怪的问题,就是分享间歇性的失效,同一个页面,刚刚调起分享成功,再试一次就失败(没有图标、title,只能跳转到首页),经过“不断”努力的尝试,应该是解决了问题,说一下过程:
一开始以为是异步唤起没成功的问题,就和 android 一样给 IOS 调用 wechatAuth 方法也加了个定时器,测了一遍没效果,放弃
起始 js-sdk 是通过 npm 安装的,版本上带了个 test,有点不放心,改为直接使用 script 标签引用官方的版本
重新读了一遍文档,发现 onMenuShareTimeline 等方法即将废弃,就把 jsApiList 改为 jsApiList:[‘updateAppMessageShareData’,’updateTimelineShareData’],改后就变成了 IOS 可以成功,android 分享失败
百度 updateAppMessageShareData 安卓失败原因,参考这个链接 https://www.jianshu.com/p/1b6e04c2944a,把老的 api 也加到 jsApiList 中,仔细、反复试了试两种设备都 ok,好像是成功了,说 ” 好像 ” 是因为心里没底啊,各种“魔法”代码!
最后,在这里希望腾讯官方能不能走点心,更新文档及时点,demo 能不能提供完整点 ….
参考链接
https://segmentfault.com/a/1190000014455713https://www.jianshu.com/p/1b6e04c2944ahttps://segmentfault.com/a/1190000012339148https://github.com/vuejs/vue-router/issues/481