为什么80%的码农都做不了架构师?>>>
背景:
鉴于微信的流行,很多的web app都会依赖于微信浏览器进行传播和推广。微信浏览器有自带的分享功能。但是若不做任何改动,直接使用此功能只会将当前页的链接分享出去,不会有自定义特色的文案。如果想要在分享的链接中加上某些参数也做不到。
平台需要一个邀请功能,用户通过点击分享按钮可以在分享的链接中带上邀请人的信息,分享出去的文案有介绍当前平台的特色,且可以不定时的更换。
那么直接分享是不能满足的,微信开发者们考虑到这方面的问题已经给出了接口供我们进行调用
时序图:
具体流程
微信之所以能够识别并正确的分享你想分享的内容,是因为我们调用了微信提供的js代码,并且给到了能够识别我们身份的信息,如唯一识别平台的appid,识别分享者信息有效的票据(加密后)signature。
1 请求后端前往微信服务端或者票据,并进行加密,然后返回给前端
1.1 带上当前的时间戳和当前平台的域名前往后端
1.2 后端调用微信提供的工具类进行票据的获取
1.3 工具类方法会封装获取token的链接,然后请求微信服务端获取token
1.4 根据获取的token,封装获取ticket的链接,然后请求微信服务的获取ticket
1.5 将拿到的ticke和传到后端的时间戳,url封装好进行加密,将加密好的数据返给前端
2 前端拿到票据加密后的数据对微信浏览器的分享按钮进行事件的初始化和绑定
代码:
wx.js
var timestamp = parseInt(new Date().getTime()/1000);
var url = window.location.href;
function WX_share(){
$.ajax({
url:'/auth/getWeixinShareInfos',
data:{timestamp:timestamp,url:url},
dataType:'json',
success:function(ret){
if (ret.code ==1 ) {
var rootPath='http://'+document.domain; // 域名
var descContent = "试客巴试用平台用效果和服务说话,帮助商家早赚钱,赚大钱"; // 分享的内容描述
var shareTitle = '2018一站式权重优化专家,7天手淘搜索破千'; // 分享的标题
var appid = 'wx9d88b*******56'; //这里写开发者接口里的appid
var imgUrl = rootPath+'/img/share_240.jpg'; //这里是分享出去的图片,一般是logo图片
var lineLink = rootPath; // 分享出去的根域名
var signature = ret.signature; // 加密后的数据
if (ret.invitecode) {
lineLink=rootPath+'/?ic='+ret.invitecode;
}
initWX(appid,timestamp,signature,lineLink,descContent,imgUrl,shareTitle);
}
}
})
}
function initWX(appid,timestamp,signature,lineLink,descContent,imgUrl,shareTitle){
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appid, // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: 'shike', // 必填,生成签名的随机串
signature: signature,// 必填,签名,见附录1
jsApiList: ['onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function(){
/* 分享到朋友圈 */
wx.onMenuShareTimeline({
title: descContent, // 分享标题
link: lineLink, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: imgUrl, // 分享图标
success: function (res) {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
/* 分享给朋友 */
wx.onMenuShareAppMessage({
title: shareTitle, // 分享标题
desc: descContent, // 分享描述
link: lineLink, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: imgUrl, // 分享图标
// type: '', // 分享类型,music、video或link,不填默认为link
// dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
/*分享到qq */
wx.onMenuShareQQ({
title: shareTitle, // 分享标题
desc: descContent, // 分享描述
link: lineLink, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
/* 分享到qq空间 */
wx.onMenuShareQZone({
title: shareTitle, // 分享标题
desc: descContent, // 分享描述
link: lineLink, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
wx.onMenuShareWeibo({
title: shareTitle, // 分享标题
desc: descContent, // 分享描述
link: lineLink, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
});
}
WXTicketUtils.java
package com.yancheng.fission.utils;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import com.yanchengtech.tools.wxpay.utils.Sha1Util;
import net.sf.json.JSONObject;
/**
* 获取微信jsapi_ticket
* @author Administrator
*
*/
@SuppressWarnings("all")
public class WXTicketUtils {
private static String APPID ="wx9d88b98******56"; // 平台对应的微信公众的appid
private static String APPSECRET="dab3deb57cd5b388*********883a6"; // 平台对应的微信公众的密钥
private static Map TICKET = new HashMap();
public static String getTicket(){
Long now = new Date().getTime();
if (TICKET.get("ticket")==null ||(TICKET.get("time")!=null && (now - Long.parseLong(TICKET.get("time")))>7200*1000)) {
//当没有ticket或者,ticket的时间超过7200秒,重新获取ticket,存放进map
String url ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
String getTicket = getToken_getTicket(url);
if (StringUtils.isNotBlank(getTicket)) {
TICKET.put("time", now.toString());
TICKET.put("ticket", getTicket);
}
}
return TICKET.get("ticket");
}
public static String getToken_getTicket(String url) {
try {
HttpClient httpClient =new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
String string = EntityUtils.toString(entity, ContentType.getOrDefault(entity).getCharset());
JSONObject obj = JSONObject.fromObject(string);
String token = obj.get("access_token").toString();
if (StringUtils.isNotBlank(token)) {
String url1="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=jsapi";
httpGet = new HttpGet(url1);
response = httpClient.execute(httpGet);
entity = response.getEntity();
string = EntityUtils.toString(entity, ContentType.getOrDefault(entity).getCharset());
obj = JSONObject.fromObject(string);
if (StringUtils.isNotBlank(obj.get("ticket").toString())) {
return obj.get("ticket").toString();
}
}
EntityUtils.consume(entity);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
觉得本文好的可以点个赞,觉得不好的可以提提建议或意见,一起进步,一起成长!!!
欢迎邮件来信讨论 [email protected]