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 相关文章推荐
优化javascript的执行效率一些方法总结
Dec 25 Javascript
jquery制作LED 时钟特效
Feb 01 Javascript
JavaScript实现同一页面内两个表单互相传值的方法
Aug 12 Javascript
ES6记录异步函数的执行时间详解
Aug 31 Javascript
Vue.js系列之项目结构说明(2)
Jan 03 Javascript
整理一些最近经常遇到的前端面试题
Apr 25 Javascript
jQuery实现广告条滚动效果
Aug 22 jQuery
bootstrap表格内容过长时用省略号表示的解决方法
Nov 21 Javascript
微信小程序如何自定义table组件
Jun 29 Javascript
解决layer 动态加载select 失效的问题
Sep 18 Javascript
如何通过JS实现转码与解码
Feb 21 Javascript
通过js实现压缩图片上传功能
Feb 25 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
PHP中SESSION的注销与清除
2015/04/16 PHP
Linux系统递归生成目录中文件的md5的方法
2015/06/29 PHP
php使用number_format函数截取小数的方法分析
2016/05/27 PHP
Laravel等框架模型关联的可用性浅析
2019/12/15 PHP
javascript据option的value值快速设定初始的selected选项
2007/08/13 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
JavaScript实现SHA-1加密算法的方法
2015/03/11 Javascript
AngularJS控制器controller正确的通信的方法
2016/01/25 Javascript
jQuery实现的指纹扫描效果实例(附演示与demo源码下载)
2016/01/26 Javascript
使用Object.defineProperty实现简单的js双向绑定
2016/04/15 Javascript
jquery.multiselect多选下拉框实现代码
2016/11/11 Javascript
15个非常实用的JavaScript代码片段
2016/12/18 Javascript
Nodejs+Socket.io实现通讯实例代码
2017/02/13 NodeJs
Bootstrap 设置datetimepicker在屏幕上面弹出设置方法
2017/03/21 Javascript
JS二叉树的简单实现方法示例
2017/04/05 Javascript
vuex学习之Actions的用法详解
2017/08/29 Javascript
jQuery 获取除某指定对象外的其他对象 ( :not() 与.not())
2018/10/10 jQuery
JavaScript时间日期操作实例小结【5个示例】
2018/12/22 Javascript
vue通过video.js解决m3u8视频播放格式的方法
2019/07/30 Javascript
解决三元运算符 报错“SyntaxError: can''t assign to conditional expression”
2020/02/12 Javascript
react实现复选框全选和反选组件效果
2020/08/25 Javascript
[45:52]完美世界DOTA2联赛PWL S3 Forest vs INK ICE 第二场 12.09
2020/12/12 DOTA
为何人工智能(AI)首选Python?读完这篇文章你就知道了(推荐)
2019/04/06 Python
Python实现合并excel表格的方法分析
2019/04/13 Python
python爬虫 模拟登录人人网过程解析
2019/07/31 Python
美国50岁以上单身人士约会平台:SilverSingles
2018/06/29 全球购物
我想声明一个指针并为它分配一些空间, 但却不行。这些代码有什么 问题?char *p; *p = malloc(10);
2016/10/06 面试题
中药专业大学生医药工作求职信
2013/10/25 职场文书
推广普通话演讲稿
2014/05/23 职场文书
法制宣传标语
2014/06/23 职场文书
医院护士党的群众路线教育实践活动对照检查材料思想汇报
2014/10/04 职场文书
2014年车间主任工作总结
2014/12/10 职场文书
会议通知范文
2015/04/15 职场文书
李强为自己工作观后感
2015/06/11 职场文书
Python实现抖音热搜定时爬取功能
2022/03/16 Python
【海涛dota解说】海涛小满开黑4v5被破两路翻盘潮汐第一视角解说
2022/04/01 DOTA