vue使用微信JS-SDK实现分享功能
作者:Jello 发布时间:2023-07-02 16:59:46
最近开发微信公众号内嵌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/ ,下载安装后,配置相应的内网映射地址
2)设置JS接口安全域
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;
}
签名接口返回信息
{
"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: () => {
}
})
}
6.遇到问题
1)invalid signature
获取的签名错误,原因可能是公众号平台配置有问题或者是后台返回签名接口的算法有问题
2)invalid url domain
当前页面所在域名与使用的appid没有绑定,请确认正确填写绑定的域名,仅支持80(http)和443(https)两个端口,因此不需要填写端口号。
3)自定义的缩略图不显示
路径错误导致的,不能使用相对路径,一定要是绝对路径,另外一个原因就是图片尺寸和类型问题,推荐使用jpg格式
4)二次分享导致不能调用自定义的接口
url进行编码之后传给后台获取的签名才不会计算错,因为微信会在分享后的链接后面加from=singlemessage&isappinstalled=0
这串字符串。
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实现分享功能,网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://segmentfault.com/a/1190000020163797
猜你喜欢
- 这篇文章主要介绍了python DataFrame转dict字典过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- 结合这个例子分析一下结果:结合以往C语言的基础,画了一张图来解释为什么会有上面这些值的出现。先查看下Go中的这两个运算符是啥吧。①对于所有带
- 最近打算在win系统下使用pycharm开发程序,并远程连接服务器调试程序,其中在import tensorflow时报错如图所示(在远程服
- 1. 图像缩放1.2. 使用命令import cv2# 缩放def resize(img, k, inter):
- 1、如何去掉字符串中不需要的字符?实际案例:(1)过滤掉用户输入前后多余的空白字符:' nick2008@gmail.com
- 一、桌面应用软件桌面应用软件是基于GUI(Graphical User Interface,图形用户界面)交互式程序,需要实现GUI库实现前
- 在日常的编程中,我经常需要标识存在于文本文档中的部件和结构,这些文档包括:日志文件、配置文件、定界的数据以及格式更自由的(但还是
- 从PDF读取文本内容和从已经有的文档生成新的PDF。需要用到的模块是PyPDF2.mstamy2/PyPDF2: A utility to
- MySQL 8 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能
- CGArt®2008“贺岁刊”玉鼠闹春,700页再造巅峰本期CGArt杂志信息:下载地址:http://cgart.cgfi
- (应一些初学者的要求,虽然本人也绝对称不上专业,但是想让一个人快速地走出初学的迷茫,需要这种精炼的集合)首先,阐明一下我的观点:不论是什么编
- 熵值法也称熵权法,是学术研究,及实际应用中的一种常用且有效的编制指标的方法。1.简单理解 信息熵机器学习中的决策树算法是对信息熵的一种典型的
- 我们知道Excel有一个match函数,可以做数据匹配。比如要根据人名获取成绩而参考表sheet1的内容如下:要根据sheet1匹配每人的成
- bsddb模块是用来操作bdb的模块,bdb是著名的Berkeley DB,它的性能非常好,mysql的存储后端引擎都支持bdb的方式。这里
- 在python 开发web程序时,需要调用第三方的相关接口,在调用时,需要对请求进行签名。需要用到unix时间戳。 在python里,在网上
- 一、什么是索引 减少磁盘I/O和逻辑读次数的最佳方法之一就是使用【索引】 索引允许SQL Server在表中查找数据而不需要扫描整个表。 1
- python和C++一样,支持多继承。概念虽然容易,但是困难的工作是如果子类调用一个自身没有定义的属性,它是按照何种顺序去到父类寻找呢,尤其
- 对于值传递和引用传递,书本上的解释比较繁琐,而php面试中总会出现,下面我会通过一个生活的例子带大家理解它们之间区别。第一步假设我们去酒店订
- 1 如何创建项目数据库首先,在虚拟机数据库中建立一个与项目同名的数据库,方便管理。(django_test) bd@DF:~$ mysql
- 项目需要就在现有的服务器上面重新安装了个mysql服务器,还挺费劲儿呢,因为之前都是在我的笔记本上面试验的,它的系统是Ubuntu的,什么路