Vue项目history模式下微信分享爬坑总结


Posted in Javascript onMarch 29, 2019

每回遇到微信分享都是一个坑,目前的商城项目使用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://3water.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://3water.com/article/158690.htm,把老的api也加到jsApiList中,仔细、反复试了试两种设备都ok,好像是成功了,说"好像"是因为心里没底啊,各种“魔法”代码!

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

参考链接

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
深入聊聊Array的sort方法的使用技巧.详细点评protype.js中的sortBy方法
Apr 12 Javascript
JavaScript 事件属性绑定带参数的函数
Mar 13 Javascript
让div层随鼠标移动的实现代码 ie ff
Dec 18 Javascript
基于jQuery的js分页代码
Jun 10 Javascript
js实现iframe自动自适应高度的方法
Feb 17 Javascript
简化版手机端照片预览组件
Apr 13 Javascript
JavaScript中继承用法实例分析
May 16 Javascript
JavaScript中的条件判断语句使用详解
Jun 03 Javascript
修改vue+webpack run build的路径方法
Sep 01 Javascript
微信小程序文章详情页面实现代码
Sep 10 Javascript
js实现淘宝首页的banner栏效果
Nov 26 Javascript
vue组件的路由高亮问题解决方法
May 11 Vue.js
vue中使用微信公众号js-sdk踩坑记录
Mar 29 #Javascript
微信小程序学习笔记之本地数据缓存功能详解
Mar 29 #Javascript
微信JS-SDK updateAppMessageShareData安卓不能自定义分享详解
Mar 29 #Javascript
详解vue配置后台接口方式
Mar 29 #Javascript
微信小程序学习笔记之获取位置信息操作图文详解
Mar 29 #Javascript
点击按钮弹出模态框的一系列操作代码实例
Mar 29 #Javascript
VUE解决微信签名及SPA微信invalid signature问题(完美处理)
Mar 29 #Javascript
You might like
社区(php&&mysql)四
2006/10/09 PHP
菜鸟学PHP之Smarty入门
2007/01/04 PHP
深入extjs与php参数交互的详解
2013/06/25 PHP
phalcon框架使用指南
2016/02/23 PHP
PHP自定义错误用法示例
2016/09/28 PHP
Zend Framework入门教程之Zend_Config组件用法详解
2016/12/09 PHP
贴一个在Mozilla中常用的Javascript代码
2007/01/09 Javascript
学习YUI.Ext 第二天
2007/03/10 Javascript
javascript之锁定表格栏位
2007/06/29 Javascript
关于js遍历表格的实例
2013/07/10 Javascript
js实现宇宙星空背景效果的方法
2015/03/03 Javascript
jquery实现多条件筛选特效代码分享
2015/08/28 Javascript
基于BootStrap的前端分页带省略号和上下页效果
2017/05/18 Javascript
JavaScript获取tr td 的三种方式全面总结(推荐)
2017/08/15 Javascript
vue this.reload 方法 配置
2018/09/12 Javascript
JS遍历JSON数组及获取JSON数组长度操作示例【测试可用】
2018/12/12 Javascript
vue模式history下在iis中配置流程
2019/04/17 Javascript
python利用不到一百行代码实现一个小siri
2017/03/02 Python
python selenium执行所有测试用例并生成报告的方法
2019/02/13 Python
django之使用celery-把耗时程序放到celery里面执行的方法
2019/07/12 Python
Django 查询数据库并返回页面的例子
2019/08/12 Python
pygame实现打字游戏
2021/02/19 Python
Pycharm导入anaconda环境的教程图解
2020/07/31 Python
python读取excel数据并且画图的实现示例
2021/02/08 Python
html5绘制时钟动画
2014/12/15 HTML / CSS
日本著名化妆品零售网站:Cosme Land
2019/03/01 全球购物
Bluebella法国官网:英国性感内衣品牌
2019/05/03 全球购物
Servlet都有哪些方法?主要作用是什么?
2014/03/04 面试题
学校食堂采购员岗位职责
2013/12/05 职场文书
交警个人先进事迹材料
2014/05/11 职场文书
学校端午节活动方案
2014/08/23 职场文书
党员弘扬焦裕禄精神思想汇报
2014/09/10 职场文书
诚信考试承诺书范文
2015/04/29 职场文书
详细聊聊MySQL中慢SQL优化的方向
2021/08/30 MySQL
Python使用mitmproxy工具监控手机 下载手机小视频
2022/04/18 Python
GO中sync包自由控制并发示例详解
2022/08/05 Golang