系列文章目录
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
前言
一、需求描述
用户在h5 页面中实现微信的分享至好友、分享至朋友圈的功能、且实现的方式为卡片的形式,(一个h5界面要求点击
右上角三个点后点击微信好友分享带标题和图片给好友。vue项目中,分享携带头部标题、简介和缩略图等信息)。


二、为什么微信有了右上角的三个点分享还需要自定义分享
自定义分享是自定义分享卡片的内容,如:内容,标题、图片、链接。
默认点击分享没有图片,文字说明等。具体分享操作还是得通过右上角的三个点分享来拉起分享面板的,通过代码拉不起来分享面板。
直接点击分享应该是没有图和文字描述的,这就是为什么需要自定义分享的原因。
三、点击链接进入网页分享后为什么不是卡片?
这也是我遇到的坑之一,从21年后微信出了新政策 ,通过链接进入的再分享出来的还是链接,卡片和扫码进来的
分享就是卡片形式。所以要想分享出去是卡片的形式,而不是链接的方式,需要通过如下几种方式:
1、以扫码的方式进入后进行分享。
2、将链接收藏,从收藏中点击进入后进行分享。
3、在微信公众号的菜单栏中进行配置链接,用户在微信公众号中点击,后进行分享。
注:如果是点击链接进入,则分享出去还是链接的形式。
四、代码示例
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
button{
width: 200px;
height: 80px;
margin: 0 10px;
background-color: salmon;
font-size: 32px;
}
</style>
<body>
<button onclick="weChatShare()">微信分享</button>
</body>
<script src="http://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
var nonce="";//生成签名的随机串
var signature="";//签名
var timestamp="";//时间戳
var title="恭喜你!中奖啦!快戳我查看吧!";
var desc="原来中奖的感觉是那么美好!";
var sharLink="http://35vri4.natappfree.cc/resources/index.html"; // 分享页面链接,即当前的页面链接
var imgUrl="http://35vri4.natappfree.cc/resources/0.jpg"; // 卡片图片
function getSign(){
let xhr = new XMLHttpRequest();
let url = "http://35vri4.natappfree.cc/index/initWXJSSDKConfigInfo";
xhr.open("GET", url+"?shareUrl=http://35vri4.natappfree.cc/resources/index.html");
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
let response = JSON.parse(xhr.responseText).data;
nonce = response.nonceStr;
signature = response.signature;
timestamp = response.timestamp;
wx.config({
debug: false,
appId: 'wxd69d5d06853a46db',
timestamp: timestamp,
nonceStr: nonce,
signature: signature,
jsApiList: ["updateAppMessageShareData","updateTimelineShareData"]
});
wx.error(err => {
console.log(err, '接口验证失败');
});
// weChatShare() 自动执行分享配置,不需要手动点击
}
};
xhr.send();
}
function weChatShare(){
wx.ready(function() {
const shareObject = {
title: title,
desc: desc,
link: sharLink,
imgUrl: imgUrl,
success: function () {
console.log("分享到朋友圈成功");
},
cancel: function () {
console.log("分享到朋友圈取消");
},
fail: function () {
console.log("分享朋友圈失败");
}
};
wx.updateAppMessageShareData(shareObject);
wx.updateTimelineShareData(shareObject);
});
}
window.onload = function (){
getSign();
}
</script>
</html>
后端
/**
* 初始化微信JSSDK配置信息
* @throws Exception
*/
@RequestMapping("/initWXJSSDKConfigInfo")
@ResponseBody
public Result<Map> initWXJSConfig (HttpServletRequest request, HttpServletResponse response, String shareUrl) throws Exception{
Map map = initJSSDKConfigInfo(shareUrl);
return Results.newSuccess(map);
}
/**
* @description 初始化JSSDK配置信息
* @param shareUrl 分享的url地址
* @throws Exception
*/
public Map initJSSDKConfigInfo(String shareUrl) throws Exception {
String accessToken = getJSSDKAccessToken().getAccessToken();
String jsapiTicket = getJSSDKJsapiTicket(accessToken).getTicket();
String timestamp = Long.toString(System.currentTimeMillis() / 1000);
String nonceStr = UUID.randomUUID().toString();
String signature = buildJSSDKSignature(jsapiTicket,timestamp,nonceStr,shareUrl);
Map<String,String> map = new HashMap<String,String>();
map.put("shareUrl", shareUrl);
map.put("jsapi_ticket", jsapiTicket);
map.put("nonceStr", nonceStr);
map.put("timestamp", timestamp);
map.put("signature", signature);
map.put("appid", "wxd69d5d06853a46db");
System.out.println("签名Message:" + map.toString());
return map;
}
/**
* @return JSSDK认证token
* @description 基础支持JSSDK的认证accessToken
*/
public AccessTokenResponse getJSSDKAccessToken() {
String url = StrFormatter.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", appId, appsecret);
String body = HttpUtil.get(url);
System.out.println("获取的accesstokne"+ body);
try {
AccessTokenResponse accessTokenResponse = objectMapper.readValue(body, AccessTokenResponse.class);
return accessTokenResponse;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* @param accessToken 基于基础支持的accessToken获取ticket
* @return 返回JSSDK的ticket
* @description 获取JSSDK的ticket
*/
public TicketResponse getJSSDKJsapiTicket(String accessToken) {
String url = StrFormatter.format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={}&type=jsapi", accessToken);
String body = HttpUtil.get(url);
System.out.println("获取的JsapiTicket" + body);
try {
TicketResponse ticketResponse = objectMapper.readValue(body, TicketResponse.class);
return ticketResponse;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static String buildJSSDKSignature(String ticket,String timestamp,String nonceStr ,String url) throws Exception {
StringBuffer signaStr = new StringBuffer();
signaStr.append("jsapi_ticket=").append(ticket);
signaStr.append("&noncestr=").append(nonceStr);
signaStr.append("×tamp=").append(timestamp);
signaStr.append("&url=").append(url);
return sha1(signaStr.toString());
}