为了增加用户的扩散速度,微信分享是绕不过的坎儿.
微信分享其实是挺简单,有现成的接口,只需要按部就班来搭建正确的调用方法就行.
分享分为app内部分享和在分享页面中使用微信自己的分享按钮(外部分享)两种.
1.内部分享,点击对应的分享按钮,代码实现如下:
function shareOnclick(ths){
jQuery('div.closeShare').addClass('display-n');
var sharemsgjson={};
var sharetype=$(ths).find("img").attr("sharetype");
sharemsgjson.sharetype=sharetype;
sharemsgjson.title='分享的标题';
sharemsgjson.content='分享的内容';
sharemsgjson.href='点击分享框的跳转链接';
sharemsgjson.thumbs=['分享logo'];
shareAction(sharemsgjson);
}
function shareAction(sharemsgjson) {
var msg = {};
var sharetype = sharemsgjson.sharetype;
var content = sharemsgjson.content;
var title = sharemsgjson.title;
var thumbs = sharemsgjson.thumbs;
var href = sharemsgjson.href;
if (sharetype == 'weixin') {
msg = {
extra: {
scene: 'WXSceneSession'
},
content: content,
title: title,
thumbs: thumbs,
href: href
};
} else if (sharetype == 'pengyouquan') {
msg = {
extra: {
scene: 'WXSceneTimeline'
},
content: content,
title: title,
thumbs: thumbs,
href: href
};
sharetype = 'weixin';
} else if (sharetype == 'sinaweibo') { // 新浪微博
msg = {
content: content,
title: title,
thumbs: thumbs,
href: href
};
}
// 朋友圈
var share = shares[sharetype];
if (share.authenticated) {
share.send(msg, function() {
mui.alert("分享到\"" + share.description + "\"成功! ");
}, function(e) {
if(e.code=="-100"){
mui.alert("未分享~");
}else{
mui.alert("分享到\"" + share.description + "\"失败: " + e.code + " - " + e.message);
}
});
} else {
share.authorize(function() {
share.send(msg, function() {
mui.alert("分享到\"" + share.description + "\"成功! ");
}, function(e) {
});
}, function(e) {
});
}
}
2.分享页面二次分享:
首先需要引用微信js:<script language=javascript src='http://res.wx.qq.com/open/js/jweixin-1.0.0.js'></script>,如果服务器时https协议,需要引用https协议的该文件.
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appid, // 必填,公众号的唯一标识
timestamp:timestamp , // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature,// 必填,签名,见附录1
jsApiList: ['onMenuShareAppMessage','onMenuShareTimeline'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.onMenuShareAppMessage({
title: '', // 分享标题
desc: '', // 分享描述
link: share_link, // 分享链接
imgUrl: firstimg, // 分享图标
type: 'link', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
console.log('好友分享成功');
},
cancel: function () {
console.log('好友分享取消');
}
});
// 分享到朋友圈
wx.onMenuShareTimeline({
title: '', // 分享标题
link: share_link, // 分享链接
imgUrl: firstimg, // 分享图标
success: function () {
console.log('朋友圈分享成功');
},
cancel: function () {
console.log('朋友圈分享取消');
}
});
wx.checkJsApi({
jsApiList: ['onMenuShareAppMessage','onMenuShareTimeline'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function(res) {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
console.log('是否支持当前接口');
console.log(res);
}
});
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
console.log('失败。。');
console.log(res);
});
服务器端实现逻辑:
ReturnDatas returnObject = ReturnDatas.getSuccessReturnDatas();
String noncestr = SecUtils.getUUID();
Long timestamp = new Date().getTime() ;
timestamp = timestamp / 1000 ;// 转换为 s
String curr_location = request.getParameter("curr_location");
String paraid = request.getParameter("paraid");
String paratype = request.getParameter("paratype");
String url = "",para = "",result = "";
String appid = "";// 测试appid
String secret = "";//测试
String METHOD = "POST";
String encode = "UTF-8";
// 获取 access_token
// 首先去数据库中查询最近一次请求的token是否在有效期,微信的有效期是2h,保险起见,本地设置为1h,避免每次都重新请求token,达到微信的2000/天 上限.
boolean need_refresh_token = false ;
String last_ticket = "";
String ticket = "";
数据字典 dd = new 数据字典();
try {
dd = dicDataService.findDicDataById("refreshaccesstoken");
} catch (Exception e) {
}
if(dd != null && StringUtils.isNotBlank(dd.getPid())){
String time_str = dd.getPid() ;
try{
long time = Long.parseLong(time_str) ;
long curr_time = System.currentTimeMillis() ;
if(curr_time - time > 3600000){ // 超过一个小时
need_refresh_token = true ;
}else{
last_ticket = dd.getCode() ;
}
}catch(NumberFormatException e){
need_refresh_token = true ;
}
}else{
need_refresh_token = true ;
}
if(need_refresh_token){ // 去微信服务器刷新token和ticket
url = " https://api.weixin.qq.com/cgi-bin/token";
para = "grant_type=client_credential&appid="+appid+"&secret="+secret;
try {
result = HttpUtils.post(url, para, METHOD, encode);
} catch (Exception e) {
}
String access_token_1 = "";
if(StringUtils.isNotBlank(result)){
HashMap<String, Object> map_result = JsonUtils.readValue(result, HashMap.class);
access_token_1 = (String)map_result.get("access_token");
}
// 根据获取的 access_token 来获取 ticket
url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
para = "access_token="+access_token_1+"&type=jsapi";
try {
result = HttpUtils.post(url, para, METHOD, encode);
} catch (Exception e) {
}
Number expires_in = null;
String errmsg = "";
if(StringUtils.isNotBlank(result)){
HashMap<String, Object> map_result = JsonUtils.readValue(result, HashMap.class);
errmsg = (String)map_result.get("errmsg");
ticket = (String)map_result.get("ticket");
expires_in = (Number) map_result.get("expires_in");
}
// 更新数据库中的token和ticket
if(StringUtils.isNotBlank(ticket) && StringUtils.isNotBlank(errmsg) && errmsg.equalsIgnoreCase("ok")){
dd.setRemarker(access_token_1);
String curr_time_str = System.currentTimeMillis()+"";
dd.setPid(curr_time_str);
dd.setCode(ticket);
if(expires_in != null ){
dd.setSort(expires_in.intValue());
}else{
dd.setSort(7200);
}
try{
dicDataService.update(dd);
}catch(Exception e){
}
}
}else{
ticket = last_ticket ;
}
HashMap<String, Object> ret = new HashMap<String, Object>();
String string1;
String signature = "";
//注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + ticket +
"&noncestr=" + noncestr +
"×tamp=" + timestamp +
"&url=" + curr_location;
System.out.println(string1);
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
System.out.println("signature:"+signature);
System.out.println("jsapi_ticket:"+ticket);
System.out.println("noncestr:"+noncestr);
System.out.println("timestamp:"+timestamp);
System.out.println("curr_location:"+curr_location);
}catch (NoSuchAlgorithmException e){
e.printStackTrace();
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
// 获取分享logo图片路径
String img_path = "";
try {
img_path = service.xxxx();
} catch (Exception e) {
}
ret.put("firstimg", img_path);
ret.put("url", curr_location);
ret.put("jsapi_ticket", ticket);
ret.put("nonceStr", noncestr);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
ret.put("appid", appid);
returnObject.setData(ret);
return returnObject ;
备注:如果不通过微信分享接口来定制实现二次分享样式,默认也是可以分享成功,只不过微信会默认抓取页面title作为分享title,抓取页面url作为分享内容,页面中的第一张图片作为默认logo(图片尺寸大小必需大于300x300).
以上.