视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Vue项目history模式下微信分享爬坑总结
2020-11-27 21:59:29 责编:小采
文档


每回遇到微信分享都是一个坑,目前的商城项目使用Vue开发,采用history的路由模式,配置微信分享又遇到了很多问题,最后终于解决了,现将解决的过程分享一下。

技术要点

Vue,history

常见问题及说明

debug模式下报false

这个没得说,就是调用wx.config方法的参数错误造成的,请确认以下事项:

  1. 是否成功绑定了域名(域名校验文件要能被访问到)
  2. 使用最新的js-sdk文件,因为微信会改部分api
  3. config方法的参数是否传正确了(拼写错误、大小写...)
  4. 需要使用的方法是否写在了jsApiList中
  5. 获取签名的url需要decodeURIComponent
  6. 后台的生成签名的加密方法需要对照官方文档

debug返回ok,分享不成功

  1. 确保代码拼写正确
  2. 分享链接域名或路径必须与当前页面对应的公众号JS安全域名一致
  3. 接口调用需要放在wx.ready方法中

单页项目(SPA)中的一些要点

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

上面那段话摘自官方文档

开发者需要注意的事项:

  1. android和ios需要分开处理
  2. 需要在页面url变化的时候重新调用wx.config方法,android获取签名的url就传window.location.href
  3. 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);
 }
});

代码要点:

  1. meta中的allowShare用于判断页面是否可分享
  2. window.__wxjs_is_wkwebview可用来判断是否是微信IOS浏览器
  3. entryUrl是项目第一次进入的页面的地址,将其缓存在window对象上
  4. 为什么安卓的时候要增加一个延时器,因为安卓会存在一些情况,就是即便签名成功,但是还是会唤不起功能,这个貌似是一个比较稳妥的解决办法

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://www.gxlcms.com/article/158685.htm,按照上面的代码,android手机都能成功,但是IOS有一个奇怪的问题,就是分享间歇性的失效,同一个页面,刚刚调起分享成功,再试一次就失败(没有图标、title,只能跳转到首页),经过“不断”努力的尝试,应该是解决了问题,说一下过程:

  1. 一开始以为是异步唤起没成功的问题,就和android一样给IOS调用wechatAuth方法也加了个定时器,测了一遍没效果,放弃
  2. 起始js-sdk是通过npm安装的,版本上带了个test,有点不放心,改为直接使用script标签引用官方的版本
  3. 重新读了一遍文档,发现onMenuShareTimeline等方法即将废弃,就把jsApiList改为jsApiList:['updateAppMessageShareData','updateTimelineShareData'],改后就变成了IOS可以成功,android分享失败
  4. 百度updateAppMessageShareData安卓失败原因,参考这个链接https://www.gxlcms.com/article/158690.htm,把老的api也加到jsApiList中,仔细、反复试了试两种设备都ok,好像是成功了,说"好像"是因为心里没底啊,各种“魔法”代码!

最后,在这里希望腾讯官方能不能走点心,更新文档及时点,demo能不能提供完整点....

参考链接

https://www.gxlcms.com/article/158685.htm
https://www.gxlcms.com/article/158693.htm
https://www.gxlcms.com/article/158690.htm
https://github.com/vuejs/vue-router/issues/481

下载本文
显示全文
专题