2019-07-02

每回遇到微信分享都是一个坑,目前的商城项目使用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://segmentfault.com/a/1190000014455713,按照上面的代码,android手机都能成功,但是IOS有一个奇怪的问题,就是分享间歇性的失效,同一个页面,刚刚调起分享成功,再试一次就失败(没有图标、title,只能跳转到首页),经过“不断”努力的尝试,应该是解决了问题,说一下过程:

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

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

参考链接

https://segmentfault.com/a/1190000014455713

https://www.jianshu.com/p/1b6e04c2944a

https://segmentfault.com/a/1190000012339148

https://github.com/vuejs/vue-router/issues/481

 

Vue项目history模式下微信分享总结的更多相关文章

  1. vue项目history模式下微信分享相关问题

    import wx from '@/utils/wx' import { shareApi } from '@/api' // 微信验证 export function requireConfig() ...

  2. vue history模式 ios微信分享坑

    vue history模式 ios微信分享坑 问题分析:因为苹果分享会是调取签名失败是因为:苹果在微信中浏览器机制和安卓不同,有IOS缓存问题,和IOS对单页面的优化问题,通俗点说安卓进行页面跳转分享 ...

  3. 在nginx上部署vue项目(history模式);

    在nginx上部署vue项目(history模式): vue-router 默认是hash模式,使用url的hash来模拟一个完整的url,当url改变的时候,页面不会重新加载.但是如果我们不想has ...

  4. 在nginx上部署vue项目(history模式)--demo实列;

    在很早之前,我写了一篇 关于 在nginx上部署vue项目(history模式) 但是讲的都是理论,所以今天做个demo来实战下.有必要让大家更好的理解,我发现搜索这类似的问题还是挺多的,因此在写一篇 ...

  5. vue history模式 ios微信分享 踩过的坑

    背景:教育项目,整体依赖于微信环境,涉及到微信分享.微信二次分享 问题:vue使用history模式在iso微信下分享设置出错(签名认证错误.分享设置失败) 问题发现路径 1.按照微信公众号官方文档设 ...

  6. nginx反向代理部署vue项目(history模式)的方法

    前言: 根据标题我们要区分出两个信息 1. history 模式部署 ( vue的路由模式如果使用history,刷新会报404错误.) 2. Nginx 做反向代理 问题1思考: vue-route ...

  7. vue hash模式下微信分享后打开首页,三种完美解决方案

    微信分享功能给我们带来了很大的便利,使得基于微信开发出来的 H5 页面可以很好的通过微信平台进行传播.所以呢,基本上每个基于微信开发的 H5 都会集成微信分享功能.但是,前几天在对接微信分享 API ...

  8. Vue项目History模式404问题解决

    本文主要解决Vue项目使用History模式发布到服务器Nginx上刷新页面404问题.(由于每个项目的情况都不尽相同,本方案已经完美解决本在所使用项目,具体情况可能还需要修改.) 1.项目背景分析 ...

  9. vue路由history模式下打包node服务器配置

    vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载. 如果不想要很丑的 hash,我们可以用路由的 his ...

随机推荐

  1. Docker如何制作镜像-Dockerfile的使用

    1:什么是Dockerfile Dockerfile是一个文本文档,可以通过docker build 命令构建成一个镜像. 我们可以在Dockerfile中定义一系列的命令,构建出我们想要的镜像. 想 ...

  2. 「影院售票系统」 · Java Swing + MySQL JDBC开发

    目录 文档说明: 一.语言和环境 二.实现功能 三.数据库设计 四.具体要求及推荐实现步骤 五.注意事项 六.评分标准 实现代码: 一.数据库: 二.Java Swing: com.ynavc.Bea ...

  3. SpringCloud创建Config读取本地配置

    1.说明 Config Server获取配置支持的方式很多, 包括Git仓库(github/gitee等),任何与JDBC兼容的数据库, Subversion,Hashicorp Vault,Cred ...

  4. 年功序列c++游戏

    题目描述 在虚拟国度里多了很多 Virtual oier,为了树立对后辈的威信,从第 11 个 Virtual oier 开始的 oier 们搞起了年功序列的制度. 虚拟国度的创始人 oier Cht ...

  5. select 1 from 是什么意思?有什么作用?

    参考:https://www.douban.com/note/518373959/ 一.select 1 from 的作用1.select 1 from mytable 与 select anycol ...

  6. ModelForm has no model class specified

    未指定模型类,错误发生在把model拼写错误 来自为知笔记(Wiz)

  7. go 使用 sort 对切片进行排序

    golang对slice的排序 golang里面需要使用sort包,并且实现几个接口Len, Swap, Less sort 包排序demo 假如现在有个slice 叫做 ids 里面保存的数据类型是 ...

  8. MySQL索引失效之隐式转换

    常见索引失效: 1. 条件索引字段"不干净":函数操作.运算操作 2. 隐式类型转换:字符串转数值:其他类型转换 3. 隐式字符编码转换:按字符编码数据长度大的方向转换,避免数据截 ...

  9. Echart可视化学习(十)

    文档的源代码地址,需要的下载就可以了(访问密码:7567) https://url56.ctfile.com/f/34653256-527823386-04154f 官网找到类似实例, 适当分析,并且 ...

  10. java邮件打包在linux备份数据库练习

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6812982512256549387/ 承接上一篇文档<Java实现163邮箱发送邮件到QQ邮箱> 主方 ...