解决SPA微信分享失效问题?!
博客专区 > zuoge85 的博客 > 博客详情
解决SPA微信分享失效问题?!
zuoge85 发表于3个月前
解决SPA微信分享失效问题?!
  • 发表于 3个月前
  • 阅读 9
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 古有ie6,今有微信browser,都是前段的梦魇。 自从上次解决微信spa(单页面应用)分享问题已经一年去了,最近又一次遇到问题。经过仔细分析先吧解决办法记录下来。 根据之前的经验对微信分享相关诡异情况进行一次总结!

IOS直接访问域名,跳转子页面不能分享的问题!!

在ios内通过http://www.abc.com 进入后跳转页面可能出现的分享失效问题!注意不带最后的”/“。
我们可以在代码内进行一次跳转来解决这个问题,注意WKWebview和UIWebview处理方式稍微不一样。

在spa应用框架未初始化的时候调用!

6

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

if (this.isIos() && location.pathname == "/") {

let baseUrl = "/account" + (location.search ? location.search : "");

//

if(window["__wxjs_is_wkwebview"]){

history.replaceState(null, null, baseUrl);

}else{

location.replace(baseUrl);

}

}

//注意排除 微信web开发者工具

let isIos = ()=>{

return /(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent) &&

!(navigator.userAgent.indexOf("wechatdevtools") > -1);

}

客户端签名

每次跳转都 需要去服务器请签名,所以如果不考虑安全可以在客户端签名

6

 

1

2

3

4

5

6

7

8

9

10

11

 

import uuidV4 from "uuid/v4";

import jsSHA from "jssha/src/sha1";

let nonceStr = uuidV4();

let timestamp = Math.ceil(new Date().getTime() / 1000);

let str1 = "jsapi_ticket=" + tokenModel.jsToken

+ "&noncestr=" + nonceStr + "&timestamp="

+ timestamp + "&url=" + url;

let shaObj = new jsSHA("SHA-1", "TEXT");

shaObj.update(str1);

let signature = shaObj.getHash("HEX");

微信文档有如下说明,但是我认为一般没问题
“3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。”

安卓和ios不同的签名过程

经过反复尝试ios 和 安卓 的签名过程如下

ios: 首次进入的location(在处理了不带路径问题后获取的location),且判定是否已经签名过,如果没签名过就签名,已经签名的url不用签名!
安卓: 每次都使用 当前location.href.split(‘#’)[0] 签名

注意最好在popstate 事件 内触发签名

6

 

1

2

3

4

5

 

window.addEventListener('popstate', (event) => {

setTimeout(()=>{

//签名

},0)

}, false);

菜单无辜消失的问题

这个问题很没有规律,但是安卓下非常容易出现,解决办法,在签名成功后立即执行一次显示全部菜单

6

 

1

 

wx.showAllNonBaseMenuItem();

完整签名代码示例

6

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

 

const shareMap = {};

let share = {

title: '标题', // 分享标题

desc: '描述!', // 分享描述

link: location.href.split('#')[0], // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致

imgUrl: location.origin + '/lips_share.jpg', // 分享图标

};

//popstate后调用

const innerInitWeixinConfig = () => {

let tokenModel = {}//启动的时候获取的签名需要信息;

if (!wx || !tokenModel) {

return;

}

let url = this.isIos() ? this._location : location.href.split('#')[0];

let nonceStr = uuidV4();

let timestamp = Math.ceil(new Date().getTime() / 1000);

let str1 = "jsapi_ticket=" + tokenModel.jsToken

+ "&noncestr=" + nonceStr + "&timestamp="

+ timestamp + "&url=" + url;

console.log("签名串", str1);

let shaObj = new jsSHA("SHA-1", "TEXT");

shaObj.update(str1);

let signature = shaObj.getHash("HEX");

if (!this.isIos() || (!shareMap[url])) {

shareMap[url] = url;

wx.config({

debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

appId: tokenModel.appid, // 必填,公众号的唯一标识

timestamp, // 必填,生成签名的时间戳

nonceStr, // 必填,生成签名的随机串

signature,// 必填,签名,见附录1

jsApiList: [

'onMenuShareTimeline',

'onMenuShareAppMessage',

'onMenuShareQQ',

'onMenuShareWeibo',

'onMenuShareQZone',

'startRecord',

'stopRecord',

'onVoiceRecordEnd',

'playVoice',

'pauseVoice',

'stopVoice',

'onVoicePlayEnd',

'uploadVoice',

'downloadVoice',

'chooseImage',

'previewImage',

'uploadImage',

'downloadImage',

'translateVoice',

'getNetworkType',

'openLocation',

'getLocation',

'hideOptionMenu',

'showOptionMenu',

'hideMenuItems',

'showMenuItems',

'hideAllNonBaseMenuItem',

'showAllNonBaseMenuItem',

'closeWindow',

'scanQRCode',

'chooseWXPay',

'openProductSpecificView',

'addCard',

'chooseCard',

'openCard'

] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2

});

wx.ready(() => {

console.log("微信jssdk 初始化正确", share);

nativeShare();

});

wx.error(function (res) {

console.log("微信jssdk 初始化失败", res);

});

} else {

nativeShare();

}

};

const nativeShare = () => {

if (share) {

wx.onMenuShareTimeline(this.share);

wx.onMenuShareAppMessage(this.share);

wx.onMenuShareQQ(this.share);

wx.onMenuShareWeibo(this.share);

wx.onMenuShareQZone(this.share);

}

wx.showAllNonBaseMenuItem();

}

参考

  1. 微信官方有下面这段不明觉厉的说明!

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

参考地址: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

  1. vue-router 项目的讨论 https://github.com/vuejs/vue-router/issues/481
标签: 微信 分享 h5
共有 人打赏支持
粉丝 0
博文 3
码字总数 0
作品 1
×
zuoge85
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: