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 相关文章推荐
jquery 元素控制(追加元素/追加内容)介绍及应用
Apr 21 Javascript
js跨浏览器的事件侦听器和事件对象的使用方法
Dec 17 Javascript
JS中frameset框架弹出层实例代码
Apr 01 Javascript
jquery 多个radio的click事件实例
Dec 03 Javascript
PHP+jquery+ajax实现分页
Dec 09 Javascript
react-router4 配合webpack require.ensure 实现异步加载的示例
Jan 18 Javascript
解决vue2.0动态绑定图片src属性值初始化时报错的问题
Mar 14 Javascript
解决vue js IOS H5focus无法自动弹出键盘的问题
Aug 30 Javascript
angular4+百分比进度显示插件用法示例
May 05 Javascript
监控微信小程序中的慢HTTP请求过程详解
Jul 05 Javascript
vue.js中ref及$refs的使用方法解析
Oct 08 Javascript
基于JS实现视频上传显示进度条
May 12 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
Yii使用migrate命令执行sql语句的方法
2016/03/15 PHP
Yii全局函数用法示例
2017/01/22 PHP
TP3.2.3框架使用CKeditor编辑器在页面中上传图片的方法分析
2019/12/31 PHP
用javascript获取地址栏参数
2006/12/22 Javascript
javascript json2 使用方法
2010/03/16 Javascript
初试jQuery EasyUI 使用介绍
2010/04/01 Javascript
JavaScript 原型与继承说明
2010/06/09 Javascript
Jquery插件之打造自定义的select标签
2011/11/30 Javascript
等待指定时间后自动跳转或关闭当前页面的js代码
2013/07/09 Javascript
使用js写的一个简易的投票
2013/11/27 Javascript
javascript事件函数中获得事件源的两种不错方法
2014/03/17 Javascript
jQuery实现可用于博客的动态滑动菜单完整实例
2015/09/17 Javascript
第二次聊一聊JS require.js模块化工具的基础知识
2016/04/17 Javascript
JavaScript弹窗基础篇
2016/04/27 Javascript
jQuery ajax方法传递中文时出现中文乱码的解决方法
2016/07/25 Javascript
vue脚手架vue-cli的学习使用教程
2017/06/06 Javascript
除Console.log()外更多的Javascript调试命令
2018/01/24 Javascript
Webpack path与publicPath的区别详解
2018/05/03 Javascript
vue中导出Excel表格的实现代码
2018/10/18 Javascript
VueJS 取得 URL 参数值的方法
2019/07/19 Javascript
关于vue项目中搜索节流的实现代码
2019/09/17 Javascript
在layui中对table中的数据进行判断(0、1)转换为提示信息的方法
2019/09/28 Javascript
[00:48]完美“圣”典2016风云人物:xiao8宣传片
2016/11/30 DOTA
Python操作json数据的一个简单例子
2014/04/17 Python
Python实现的数据结构与算法之双端队列详解
2015/04/22 Python
Python模块的加载讲解
2019/01/15 Python
python3实现斐波那契数列(4种方法)
2019/07/15 Python
使用Python内置模块与函数进行不同进制的数的转换
2020/04/26 Python
解决Alexnet训练模型在每个epoch中准确率和loss都会一升一降问题
2020/06/17 Python
白岩松演讲
2014/05/21 职场文书
大学生简历求职信
2014/06/24 职场文书
乡镇创先争优活动总结
2014/08/28 职场文书
2014年电厂工作总结
2014/12/04 职场文书
2014年审计人员工作总结
2014/12/19 职场文书
玄武湖导游词
2015/02/05 职场文书
详解Python魔法方法之描述符类
2021/05/26 Python