操作前必看
微信自带的点击按钮分享已经下架了,目前只支持在微信浏览器点击右上角的分享,自己配置分享参数,而且目前分享参数也无法使用。
原因:响应国家反垄断规章,微信调整可实现访问外链;
异常:现在点击微信聊天发出来的链接,再点分享会直接成为字符串链接形式
解决办法:
1.将链接添加至公众号的自定义菜单中,从公众号菜单进入分享
2.扫描二维码分享
3.将链接保存至微信收藏中,从我的收藏进入分享
其余其他地方进入分享都是链接形式
注意
切记缓存 jsapi_ticket
和 accessToken
,每天的请求有限制
若没有公众号
,那么申请测试号进行测试,但是必须有域名,目前的内网穿透工具好像都无法使用了
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
进入上方网址,微信扫码登录即可得到一个拥有微信分享权限的测试号。暂时只需要appID和appsecret。JS接口安全域名填自己的域名,不需要带http/https。接口配置信息配置需要我们完成后端代码才能配置。
微信分享接口
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping(value = "/wechatshare")
public class WeChatShareController {
private final static Logger log = LoggerFactory.getLogger(WeChatShareController.class);
/**
* 获取微信加密信息
* @return
*/
@RequestMapping(value = "/getsignature")
@ResponseBody
public Map<String, Object> toTranscript(String urls) {
Map<String, Object> data = new HashMap<String, Object>();
Map<String, Object> wxInfo = new HashMap<>();
try {
String accessToken = WeChatUitl.getAccessToken();
String jsapiTicket = WeChatUitl.getTicket(accessToken);
String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串
String timestamp = String.valueOf(System.currentTimeMillis()/ 1000);// 时间戳
String params = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url;
//将字符串进行sha1加密
String signature = WeChatUitl.getSHA1(params);
//微信appId
String appId = WeChatUitl.appIdWx;
wxInfo.put("appId", appId);
wxInfo.put("accessToken", accessToken);
wxInfo.put("jsapi_ticket", jsapiTicket);
wxInfo.put("timestamp", timestamp);
wxInfo.put("nonceStr", noncestr);
wxInfo.put("signature", signature);
wxInfo.put("msg", "success");
wxInfo.put("status", "1");
wxInfo.put("code", "1");
log.info("微信分享成功");
return wxInfo;
} catch (Exception e) {
wxInfo.put("code", "0");
wxInfo.put("status", "0");
wxInfo.put("msg", "error");
log.error("获取微信加密信息" + e.getMessage(), e);
return wxInfo;
}
}
}
微信分享工具类
import net.sf.json.JSONObject;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class WeChatUitl {
// 获取token的描述,自己定义就可以了
public static final String tokenWx = "xxxxxxxxxxxxxxx";
// 微信appid---微信公众平台
public static final String appIdWx = "xxxxxxxxxxxxxx";
// 微信AppSecret---微信公众平台
public static final String appSecretWx = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
/**
* 获取access_token
*
* @return
*/
public static synchronized String getAccessToken() {
String access_token = "";
String grant_type = "client_credential";//获取access_token填写client_credential
//这个url链接地址和参数皆不能变
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grant_type + "&appid=" + appIdWx + "&secret=" + appSecretWx;
try {
URL urlGet = new URL(url);
HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
http.setRequestMethod("GET"); // 必须是get方式请求
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
http.connect();
InputStream is = http.getInputStream();
int size = is.available();
byte[] jsonBytes = new byte[size];
is.read(jsonBytes);
String message = new String(jsonBytes, "UTF-8");
JSONObject demoJson = JSONObject.fromObject(message);
access_token = demoJson.getString("access_token");
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return access_token;
}
/**
* 获取jsapi_ticket
*
* @param access_token
* @return
*/
public static synchronized String getTicket(String access_token) {
String ticket = null;
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";//这个url链接和参数不能变
try {
URL urlGet = new URL(url);
HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
http.setRequestMethod("GET"); // 必须是get方式请求
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
http.connect();
InputStream is = http.getInputStream();
int size = is.available();
byte[] jsonBytes = new byte[size];
is.read(jsonBytes);
String message = new String(jsonBytes, "UTF-8");
JSONObject demoJson = JSONObject.fromObject(message);
System.out.println("JSON字符串:" + demoJson);
ticket = demoJson.getString("ticket");
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return ticket;
}
/**
* SHA、SHA1加密
*
* @parameter: str:待加密字符串
* @return: 加密串
**/
public static String getSHA1(String str) {
try {
MessageDigest digest = java.security.MessageDigest
.getInstance("SHA-1"); //如果是SHA加密只需要将"SHA-1"改成"SHA"即可
digest.update(str.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexStr = new StringBuffer();
// 字节数组转换为 十六进制 数
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexStr.append(0);
}
hexStr.append(shaHex);
}
return hexStr.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}
h5页面示例
$(function () {
var winUrl = window.location.href.split("#")[0];
/* if(winUrl.indexOf('from=singlemessage')>0 || winUrl.indexOf('isappinstalled')>0){
winUrl = winUrl.split('?from=singlemessage')[0]
} */
var meta = document.getElementsByTagName('meta');
var share_desc = '';
for (i in meta) {
if (typeof meta[i].name != "undefined" && meta[i].name.toLowerCase() == "description") {
share_desc = meta[i].content;
}
}
$.ajax({
type: "post",
url: "/post/getShareSignature",
crossDomain: true,
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
"articleUrl": encodeURIComponent(winUrl)
}),
success: function (msg) {
//console.log(" timestamp:" + msg.data.timestamp + " ; noncestr:" + msg.data.noncestr + "; signature:" + msg.data.signature);
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: "wx91f855a7c7f4187b", // 必填,公众号的唯一标识
timestamp: msg.data.timestamp, // 必填,生成签名的时间戳
nonceStr: msg.data.noncestr, // 必填,生成签名的随机串
signature: msg.data.signature, // 必填,签名,见附录1
jsApiList: ['onMenuShareTimeline',
'onMenuShareAppMessage'
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function () {
var title, img_url;
if (winUrl.indexOf('post') != -1) {
//IOS系统分享时读取图片路径会出现问题 用 encodeURI 来处理下
title = $("#articleTitle").val();
img_url = encodeURI($("#coverImg").val());
} else if (winUrl.indexOf('school') != -1) {
title = document.title;
img_url = encodeURI($("#schoolBadge").attr("src"));
} else if (winUrl.indexOf('seventy') != -1) {
title = document.title;
img_url = encodeURI('https://xsn.com.cn/fileDir/cnypaData/seventy.jpg');
} else {
title = document.title;
img_url = encodeURI(location.href.split('.cn/')[0] + '.cn/img/Group.png')
}
//分享到朋友圈
wx.onMenuShareTimeline({
title: title, // 分享标题
link: winUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: img_url, // 分享图标
success: function () {
console.log('已分享');
},
cancel: function () {
console.log('已取消');
},
fail:function(res){
alert(JSON.stringify(res))
}
}); //分享给微信好友
wx.onMenuShareAppMessage({
title: title, // 分享标题
desc: share_desc,
link: winUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: img_url, // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
success: function () {
console.log('已分享');
},
cancel: function () {
console.log('已取消');
},
fail:function(res){
alert(JSON.stringify(res))
}
});
wx.error(function (res) {
console.log("res:", res)
})
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log("error" + errorThrown);
}
});
})
// 微信js - sdk分享 end