vue使用微信JS-SDK实现分享功能


Posted in Javascript onAugust 23, 2019

最近开发微信公众号内嵌H5页面,使用vue搭建的项目,由于业务需求,需要实现微信自定义分享功能,所以项目中集成微信JS-SDK。微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

1.绑定域名

微信公众号开发测试帐号:  http://mp.weixin.qq.com/debug ...  ,需要填写接口配置,一个公网能访问的域名,推荐用natapp/路由侠。填写JS接口安全域名 ,设置JS接口安全域后,通过关注该测试号,开发者即可在该域名下调用微信开放的JS接口,请阅读 微信JSSDK开发文档

1)这里使用路由侠,实现内网穿透  http://www.luyouxia.com/   ,下载安装后,配置相应的内网映射地址

vue使用微信JS-SDK实现分享功能

2)设置JS接口安全域

vue使用微信JS-SDK实现分享功能

2.引入JS文件

通过npm安装微信的js-sdk,或者在index.html页面中直接加script标签来引用,这里采用npm安装,

npm install weixin-js-sdk

在需要分享的页面中引入

import wx from 'weixin-js-sdk'

3.java实现js-sdk权限签名算法

1)jsapi_ticket

生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket。

2)获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token)

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token,官方文档:

https://mp.weixin.qq.com/wiki ...

@RequestMapping(value = "/get_access_token", method = RequestMethod.GET)
public String getAssessToken() {
  String url = "https://api.weixin.qq.com/cgi-bin/token";
  String str = HttpClientUtil.sendGet(url, "grant_type=" + Constants.GRANTTYPE + "&secret=" + Constants.APPSECRET + "&appid=" + Constants.APPID);
  JSONObject jsonObject = JSONObject.fromObject(str);
  return jsonObject.toString();
}

3)获取access_token后,采用http GET方式请求获得jsapi_ticket

@RequestMapping(value = "/get_ticket", method = RequestMethod.GET)
public String getTicket() {
  String urlToken = "https://api.weixin.qq.com/cgi-bin/token";
  String tokenObj = HttpClientUtil.sendGet(urlToken, "grant_type=" + Constants.GRANTTYPE + "&secret=" + Constants.APPSECRET + "&appid=" + Constants.APPID);
  JSONObject jsonToken = JSONObject.fromObject(tokenObj);
  String access_token = jsonToken.getString("access_token");

  String urlTicket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
  String strTicket = HttpClientUtil.sendGet(urlTicket, "type=jsapi" + "&access_token=" + access_token);
  JSONObject jsonTicket = JSONObject.fromObject(strTicket); 
  return jsonTicket.toString();
}

4)签名算法

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

//主要代码
 @RequestMapping(value = "/get_signature", method = RequestMethod.GET)
public Map<String, String> getSignature(String url) {
  Map<String, String> ret = new HashMap<String, String>();

  String wxTicket = getWxApiTicket();
  String nonce_str = create_nonce_str();
  String timestamp = create_timestamp();
  String str;
  String signature = "";
  //注意这里参数名必须全部小写,且必须有序
  str = "jsapi_ticket=" + wxTicket +
      "&noncestr=" + nonce_str +
      "×tamp=" + timestamp +
      "&url=" + url;
  logger.info(str);

  try {
    MessageDigest crypt = MessageDigest.getInstance("SHA-1");
    crypt.reset();
    crypt.update(str.getBytes("UTF-8"));
    signature = byteToHex(crypt.digest());
  } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
  } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
  }

  ret.put("url", url);
  ret.put("jsapi_ticket", wxTicket);
  ret.put("nonceStr", nonce_str);
  ret.put("timestamp", timestamp);
  ret.put("signature", signature);
  ret.put("appId", Constants.APPID);
  return ret;
}

签名接口返回信息

vue使用微信JS-SDK实现分享功能

{
  "signature":"4021b3f502e6bd15798a0433af33c4ef1be4ff83",
  "appId":"wx618f45e4948c3889",
  "jsapi_ticket":"sM4AOVdWfPE4DxkXGEs8VOxnOWlkG3Q1qP1pwA8mBLNgkCewNOfFiU8EmlnAx8_Fe0Zh-rGS03Nu8BQZB0a4-g",
  "url":null,
  "nonceStr":"ab5d0e96-429b-4a86-bd88-dc1276dcf76f",
  "timestamp":"1566527616"
}

注意事项

1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。

2.签名用的url必须是调用JS接口页面的完整URL。

3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。

4.通过config接口注入权限验证配置

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

wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '', // 必填,公众号的唯一标识
  timestamp: , // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
  jsApiList: [] // 必填,需要使用的JS接口列表
});

config配置里面的参数appid, timestamp, nonceStr, signature都是要后台接口返回的,前端可以通过axios发送接口请求获取

this.axios.get('/wx/get_signature?url=' + encodeURIComponent(location.href.split('#')[0])).then((res) => {
 wx.config({
  debug: true, // 开启调试模式
  appId: res.data.appId, // 必填,公众号的唯一标识
  timestamp: res.data.timestamp, // 必填,生成签名的时间戳
  nonceStr: res.data.nonceStr, // 必填,生成签名的随机串
  signature: res.data.signature,// 必填,签名
  jsApiList: [
   "updateAppMessageShareData",//自定义“分享给朋友”及“分享到QQ”按钮的分享内容
   "updateTimelineShareData",//自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容
   "onMenuShareWeibo",//获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口
  ] // 必填,需要使用的JS接口列表
 })
}).catch((error) => {
 console.log(error)
});

//通过ready接口处理成功验证
wx.ready(function(){
  this.wxShareTimeline();
  this.wxShareAppMessage();
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});

wx.error(function(res){
//config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});

5.实现自定义分享朋友/朋友圈

wxShareTimeline() {// 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
  wx.updateAppMessageShareData({
   title: '世界那么大,我想去看看-微信test', // 分享标题
   desc: '世界那么大,我想去看看-微信test', // 分享描述
   link: location.href.split('#')[0], // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
   imgUrl: 'http://www.baidu.com/FpEhdOqBzM8EzgFz3ULByxatSacH', // 分享图标
   success: () => {
   }
  })
 },
 wxShareAppMessage() {//自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容
  wx.updateTimelineShareData({
   title: '世界那么大,我想去看看-微信test2', // 分享标题
   desc: '世界那么大,我想去看看-微信test2', // 分享描述
   link: location.href.split('#')[0], // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
   imgUrl: require('./logo.jpg'), // 分享图标(不能赋相对路径,一定要是绝对路径)
   success: () => {
   }
  })
 }

vue使用微信JS-SDK实现分享功能

6.遇到问题

1)invalid signature

获取的签名错误,原因可能是公众号平台配置有问题或者是后台返回签名接口的算法有问题

2)invalid url domain

当前页面所在域名与使用的appid没有绑定,请确认正确填写绑定的域名,仅支持80(http)和443(https)两个端口,因此不需要填写端口号。

3)自定义的缩略图不显示

路径错误导致的,不能使用相对路径,一定要是绝对路径,另外一个原因就是图片尺寸和类型问题,推荐使用jpg格式

4)二次分享导致不能调用自定义的接口

url进行编码之后传给后台获取的签名才不会计算错,因为微信会在分享后的链接后面加from=singlemessage&isappinstalled=0这串字符串。

vue使用微信JS-SDK实现分享功能

7.全局缓存公众号access_token 和jsapi_ticket

1)通过数据库保存

做法是获取access_token的时候把当前系统时间和access_token保存到数据表中,当再次获取时,查询上次获取的时间与当前系统时间比较,看看时间是否大于2个小时(7200s)。如果超过这个时间限制,再获取一个access_token,然后更新数据表的accessToken和getTime。

2)通过物理磁盘创建txt文件保存

3)通过servlet启动线程,让线程定时执行获取

可以参考 https://blog.csdn.net/guobinh ...

以上便是这次调用微信js-sdk总结,想要了解更多可以阅读微信JS-SDK说明文档 https://mp.weixin.qq.com/wiki.. .

总结

以上所述是小编给大家介绍的vue使用微信JS-SDK实现分享功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
js中if语句的几种优化代码写法
Mar 12 Javascript
IE6、IE7中setAttribute不支持class/for/rowspan/colspan等属性
Aug 28 Javascript
JQuery获取文本框中字符长度的代码
Sep 29 Javascript
js控制的回到页面顶端goTop的代码实现
Mar 20 Javascript
详细介绍jQuery.outerWidth() 函数具体用法
Jul 20 Javascript
js控制多图左右滚动切换效果代码分享
Aug 26 Javascript
jquery弹出遮掩层效果【附实例代码】
Apr 28 Javascript
JS定时器使用,定时定点,固定时刻,循环执行详解
May 31 Javascript
AngularJS2中一种button切换效果的实现方法(二)
Mar 27 Javascript
详解Vue微信公众号开发踩坑全记录
Aug 21 Javascript
解决vue项目运行提示Warnings while compiling.警告的问题
Sep 18 Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
Oct 18 Javascript
VUE实现移动端列表筛选功能
Aug 23 #Javascript
简述ES6新增关键字let与var的区别
Aug 23 #Javascript
微信小程序后台持续定位功能使用详解
Aug 23 #Javascript
详解基于Vue/React项目的移动端适配方案
Aug 23 #Javascript
详解vue-video-player使用心得(兼容m3u8)
Aug 23 #Javascript
使用vue实现多规格选择实例(SKU)
Aug 23 #Javascript
jquery分页优化操作实例分析
Aug 23 #jQuery
You might like
thinkPHP模板中函数的使用方法示例
2016/11/30 PHP
PHP 表单提交及处理表单数据详解及实例
2016/12/27 PHP
thinkPHP框架自动填充原理与用法分析
2018/04/03 PHP
jQuery 常见开发使用技巧总结
2009/12/26 Javascript
JQUERY对单选框(radio)操作的小例子
2013/04/25 Javascript
Javascript window对象详解
2014/11/12 Javascript
js jquery获取当前元素的兄弟级 上一个 下一个元素
2015/09/01 Javascript
AngularJS 实现按需异步加载实例代码
2015/10/18 Javascript
Three.js学习之正交投影照相机
2016/08/01 Javascript
使用Dropzone.js上传的示例代码
2017/10/10 Javascript
详解JS模块导入导出
2017/12/20 Javascript
[56:38]DOTA2-DPC中国联赛正赛Aster vs Magma BO3 第一场 3月5日
2021/03/11 DOTA
python实现将文本转换成语音的方法
2015/05/28 Python
剖析Django中模版标签的解析与参数传递
2015/07/21 Python
Python实现判断一个字符串是否包含子串的方法总结
2017/11/21 Python
解决python使用open打开文件中文乱码的问题
2017/12/29 Python
Python基于OpenCV实现视频的人脸检测
2018/01/23 Python
Python中enumerate()函数编写更Pythonic的循环
2018/03/06 Python
使用Scrapy爬取动态数据
2018/10/21 Python
计算机二级python学习教程(2) python语言基本语法元素
2019/05/16 Python
利用python实现汉字转拼音的2种方法
2019/08/12 Python
python属于解释语言吗
2020/06/11 Python
仿CSDN Blog返回页面顶部功能实现原理及代码
2013/06/30 HTML / CSS
戴尔加拿大官网:Dell加拿大
2016/09/17 全球购物
有750多个顶级品牌的瑞士时尚在线:ABOUT YOU
2017/01/04 全球购物
世界最大的海报和艺术印刷商店:AllPosters.com
2017/02/01 全球购物
爱尔兰领先的在线体育用品零售商:theGAAstore
2018/04/16 全球购物
几道Web/Ajax的面试题
2016/11/05 面试题
一个大学生十年的职业规划
2014/01/17 职场文书
父亲节活动策划方案
2014/08/24 职场文书
党员批评与自我批评发言材料
2014/10/14 职场文书
批评与自我批评发言稿
2014/10/15 职场文书
品质保证书格式
2015/02/28 职场文书
签约仪式致辞
2015/07/30 职场文书
实验心得体会范文
2016/01/25 职场文书
导游词之宁夏贺兰山岩画
2019/11/08 职场文书