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 flash激活
Oct 19 Javascript
Javascript中的window.event.keyCode使用介绍
Apr 26 Javascript
js判断选择时间不能小于当前时间的示例代码
Sep 24 Javascript
JS提交form表单实例分析
Dec 10 Javascript
jQuery过滤选择器经典应用
Aug 18 Javascript
JS自定义函数对web前端上传的文件进行类型大小判断
Oct 19 Javascript
jQuery扩展实现text提示还能输入多少字节的方法
Nov 28 Javascript
JS+HTML5实现图片在线预览功能
Jul 22 Javascript
基于Vue2实现简易的省市区县三级联动组件效果
Nov 05 Javascript
js实现ATM机存取款功能
Oct 27 Javascript
js实现简单的秒表
Jan 16 Javascript
原生js实现的观察者和订阅者模式简单示例
Apr 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使用literal防止模板标签被解析的方法
2014/11/22 PHP
如何使用PHP对网站验证码进行破解
2015/09/17 PHP
在php中设置session用memcache来存储的方法总结
2016/01/14 PHP
Laravel学习教程之从入口到输出过程详解
2017/08/27 PHP
利用XMLHTTP传递参数在另一页面执行并刷新本页
2006/10/26 Javascript
JavaScript面向对象之体会[总结]
2008/11/13 Javascript
javascript题目,重写函数让其无限相加
2012/02/15 Javascript
六款帮助你实现惊艳视差滚动效果的jQuery插件
2012/09/14 Javascript
js二级地域选择的实现方法
2013/06/17 Javascript
jquery html动态生成select标签出问题的解决方法
2013/11/20 Javascript
jQuery在ul中显示某个li索引号的方法
2015/03/17 Javascript
JS实现两表格里数据来回转移的方法
2015/05/28 Javascript
jQuery图片加载显示loading效果
2016/11/04 Javascript
Omi v1.0.2发布正式支持传递javascript表达式
2017/03/21 Javascript
javascript函数的节流[throttle]与防抖[debounce]
2017/11/15 Javascript
浅谈vue中.vue文件解析流程
2018/04/24 Javascript
微信小程序实现默认第一个选中变色效果
2018/07/17 Javascript
取消Bootstrap的dropdown-menu点击默认关闭事件方法
2018/08/10 Javascript
Nodejs使用Mongodb存储与提供后端CRD服务详解
2018/09/04 NodeJs
Python 元组(Tuple)操作详解
2014/03/11 Python
Python爬虫框架Scrapy实战之批量抓取招聘信息
2015/08/07 Python
浅谈python中列表、字符串、字典的常用操作
2017/09/19 Python
使用Python &amp; Flask 实现RESTful Web API的实例
2017/09/19 Python
Python通过Pygame绘制移动的矩形实例代码
2018/01/03 Python
python 定时器每天就执行一次的实现代码
2019/08/14 Python
Python利用FFT进行简单滤波的实现
2020/02/26 Python
Python 删除List元素的三种方法remove、pop、del
2020/11/16 Python
python实现简单的学生管理系统
2021/02/22 Python
基于Canvas+Vue的弹幕组件的实现
2019/07/23 HTML / CSS
波兰在线香水店:Perfumy.pl
2019/08/12 全球购物
DataReader和DataSet的异同
2014/12/31 面试题
售后服务承诺书范文
2014/03/26 职场文书
2015年七一建党节活动方案
2015/05/05 职场文书
培根随笔读书笔记
2015/07/01 职场文书
8g内存用python读取10文件_面试题-python 如何读取一个大于 10G 的txt文件?
2021/05/28 Python
table不让td文字溢出操作方法
2022/12/24 HTML / CSS