正常分享出来的H5页面状态:
如果分享出来的时候,上方两个红色框框的信息不是正常显示,那么分享就是不成功的。
思路:
1、要使用微信的H5分享,必须先有一个微信公众号,获取公众号的appId和appSecret,微信公众号记得得设置JS接口安全域名和业务域名。
2、调用微信API获取jsapi_ticket和access_token。注意:API的每天调用次数有限,默认2000次,每次请求有效期为2个小时,最好使用缓存/存储数据库;这里我已经申请提高API调用次数,所以直接每次请求都可以调用API,不需要考虑不够用的问题。
3、将appId(唯一标识)、jsapi_ticket(微信卡券JS API的临时票据)、noncestr(随机串)、timestamp(时间戳)和url(H5页面网址链接)生成加密签名后,将所有参数数据传到H5页面,再通过 wx.config 接口配置注入参数。
签名算法验证工具:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
微信开发文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#4
官方的示例代码:http://demo.open.weixin.qq.com/jssdk/sample.zip
Java代码
------------------------ WeChatShareController ------------------------
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;
}
}
}
------------------------ WeChatUitl ------------------------
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及js代码
<!--微信H5页面 index.html 引入js代码-->
<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<!-- 微信H5页面 index.html-->
<script>
//_wx.share1 发送给朋友
//_wx.share2 分享到朋友圈
;(function(){
_wx.share1={
title: '卧槽!看不懂这些动图,你不配做个程序员', // 分享标题
desc: '开心一笑,让快乐传播下。',//分享摘要
link: _wx.baseLink + 'index.html', // 分享链接
imgUrl: _wx.baseLink + 'img/share.jpg', // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
//分享成功
if(window.game){
game.fuhuo();
}
try {
MtaH5.clickStat('share_ok', {
'write': 'true'
}); //腾讯分享统计
MtaH5.clickStat("share_friends");
} catch (e) {
}
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
};
Object.assign(_wx.share2,_wx.share1);
_wx.share2.title = "卧槽!看不懂这些动图,你不配做个程序员";
_wx.share2.success=function(){
//分享成功
if(window.game){
game.fuhuo();
}
try{MtaH5.clickStat("share_circlefriends");}
catch(e){}
}
_wx.init();
})();
</script>
<!-- js代码 wx.js-->
(function () {
window._wx = {
baseLink: document.URL.substring(0, document.URL.lastIndexOf("/") + 1),
config: {
debug: false, //是否开启调试模式
jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'hideMenuItems', 'startRecord', 'stopRecord', 'onVoiceRecordEnd', 'playVoice', 'pauseVoice', 'onVoicePlayEnd', 'uploadVoice', 'downloadVoice', 'translateVoice', 'hideAllNonBaseMenuItem'],
hideMenuItems: {
menuList: ['menuItem:share:qq', 'menuItem:share:weiboApp']
},
IsHideMenu: false //隐藏高级功能菜单
},
share1: {}, //分享朋友
share2: {} //分享朋友圈
};
_wx.init = function (callbacks) {
$.ajax({
url: 'https://www.abc.cn/wx/wechatshare/getsignature',
type: 'POST',
data: {
"urls": window.location.href
},
dataType: 'json',
success: function (msg) {
msg = msg.data.wxInfo;
if (msg.status === "1") {
setting(msg);
if (callbacks) callbacks();
}
}
});
}
function setting(msg) {
wx.config({
debug: _wx.config.debug,
appId: msg.appId, // 必填,公众号的唯一标识
timestamp: msg.timestamp, // 必填,生成签名的时间戳
nonceStr: msg.nonceStr, // 必填,生成签名的随机串
signature: msg.signature, // 必填,签名,见附录1
jsApiList: _wx.config.jsApiList
});
wx.ready(function () {
wx.hideMenuItems(_wx.config.hideMenuItems);
//分享给朋友
wx.onMenuShareAppMessage(_wx.share1);
//分享到朋友圈
wx.onMenuShareTimeline(_wx.share2);
if (_wx.config.IsHideMenu) {
wx.hideAllNonBaseMenuItem();
}
});
wx.error(function (res) {});
}
})();