微信公众号网页项目】Vue+Springboot微信公众号网页项目,自定义“分享给朋友,分享到QQ”和“分享到朋友圈,分享到QQ空间”按钮的分享内容
上篇文章讲解了用户在微信客户端打开网页后,获取access_token并使用其获取用户信息,本篇文章我们继续进行微信公众号网页项目中自定义分享内容的讲解
一、准备工作
查看开发文档,确定基本步骤,开发文档链接:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
这里我们可以看到加载config时所需的内容数据,这里数据我们统一使用get_wx_information接口返回获取
1、首先,我们需要在使用JS-SDK的页面引入wx包
2、在vue页面的method方法中,创建方法;查看文档明确说明,首先使用wx.config注入权限验证配置
3、验证成功后,使用wx.ready方法加载api的基本配置
二、开始开发
- 在config参数中,比较难的是signature,签名的生成,这里我们查看一下官方文档
- 签名前首先要获取access_token,使用access_token获取jsapi_ticket,最后使用jsapi_ticket配合其他参数进行签名
- 这里的access_token与获取用户信息使用的不一样,获取access_token的请求地址为:/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET
- 获取access_token以及jsapi_ticket在这里就不详细说明了,大家可以查看博主的上一篇文章,替换其中的网址参数即可
- 随后使用access_token请求ticket接口,获取jsapi_ticket
index.vue
<script>
import wx from 'weixin-js-sdk' //引入SDK
import { get_wx_information, get_wx_access_token , get_wx_jsapi_ticket} from '@/api/http.js' // 后端接口,返回wx.config中的基本信息
export default {
data(){
return {
wx_information:null,
share_data:{
share_title:"", //分享标题
share_description:"", //分享描述
share_img:""// 分享图片,建议使用服务器或者网络图片,本地图片会加载不出来
}
}
},
method:{
async wx_information_setting(){
const access_token = JSON.parse(await get_wx_access_token().response).access_token
const ticket = JSON.parse(await get_wx_jsapi_ticket().response).ticket
const url = "http://192.168.3.28:8080/index&code=" + code + "&state=STATE" // 如果需要添加其他中文参数需要encode转码
// const url = "http://192.168.3.28:8080/index?name="+ encodeURLComponet("看海") +"&code=" + code + "&state=STATE"
get_wx_information(ticket,url).then((res) => {
this.wx_information = res.data
})
},
async reload_wx_setting(){
var that = this
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端console.log出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: "*********", // 必填,公众号的唯一标识appid
timestamp: that.wx_information.timestamp, // 必填,生成签名的时间戳
nonceStr: that.wx_information.nonceStr, // 必填,生成签名的随机串
signature: that.wx_information.signature, // 必填,签名
jsApiList: [
'onMenuShareAppMessage', // “分享给朋友”及“分享到QQ”
'onMenuShareTimeline', // “分享到朋友圈”及“分享到QQ空间”
],
})
wx.ready(function () {
wx.onMenuShareTimeline({
title: that.share_data.share_title, // 分享标题
desc: that.share_data.share_description, // 分享描述
link: "http://192.168.3.28:8080/index", // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致,注意更换为本地地址
imgUrl:that.share_data.share_img, // 分享图标
success: function (res) {}, //分享成功后进行的操作
})
wx.onMenuShareAppMessage({
title: that.share_data.share_title, // 分享标题
desc: that.share_data.share_description, // 分享描述
link: "http://192.168.3.28:8080/index", // 注意更换为本地地址
imgUrl:that.share_data.share_img, // 分享图标
success: function (res) {},
})
})
}
}
}
</script>
WxSdkController.java
private static String create_nonce_str() { // 创建自定义字符串函数,大家也可以使用其他方法,方法不限
return UUID.randomUUID().toString();
}
private static String create_timestamp() { // 获取当前时间戳
return Long.toString(System.currentTimeMillis() / 1000);
}
private static String byteToHex(final byte[] hash) { // 编码函数
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
@GetMapping("/get_wx_information")
public Map<String, Object> get_wx_information(@RequestParam String jsapi_ticket, @RequestParam String url) {
Map<String, Object> ret = new HashMap<String, Object>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
//注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"×tamp=" + timestamp +
"&url=" + url;
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Map<String, Object> map = new HashMap<>();
map.put("code", 200);
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", Integer.parseInt(timestamp));
ret.put("signature", signature);
map.put("data", ret);
return map;
}
三、测试结果
-
JS-SDK加载成功(config:ok),分享给朋友
-
加载失败(config:fail,invalid signature),错误的签名
⚠️:签名错误是最常见的错误,一般有以下几个地方容易出错
- 链接中的参数没有全部参与到签名环节;检查在进入网页后最后展示的网址 是否和 进行签名的网址一样
- 进行签名时有明确的顺序,请检查顺序
- 编码方式,请求方式是否正确等等