大家好,我是菜鸡Ha
前端时间的业务需求有微信分享,那么我光荣的接下了这个任务,现在跟大家分享下心得,最容易出错的地方:
1.签名
2.分享的时候没有显示分享标题,分享内容,这里是分享链接有误,所以大家要仔细
3.仔细仔细再仔细,按照下面的方法,应该问题不大
官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
开始之前,我们先配置一点小东西
设置完成后,我们开始吧
1,js代码
1.1 引用官方js
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
1.2 js代码(这个只提供了分享朋友圈跟好友,如果你要做QQ分享,微博什么的,那么继续在下面添加代码,官方文档里有)
$(function () {
getSgt(window.location.href.split('#')[0]);
})
//-------------begin
//设置分享内容
var title="分享标题";
var desc="分享内容";
var indexHref = window.location.href;
var shareLink=indexHref.toString();//分享链接
var shareImgUrl="http://img2.imgtn.bdimg.com/it/u=314418824,598838400&fm=26&gp=0.jpg";//分享图片
//-------------end
function getSgt(currUrl) {
$.ajax({
type: "POST",
url: "/weixin/sgture.do?url="+encodeURIComponent(window.location.href.split('#')[0]),
dataType: "json",
success: function (response) {
initWeChat(response.sgture,response.appid,response.shijianchuo,response.suijichuan);
ready();
}
});
}
function ready() {
wx.ready(function () {
if (title == null || title == '') {
alert("title is not null")
}
if (shareLink == null || shareLink == '') {
alert("shareLink is not null")
}
//分享到---朋友圈,微信好友
onMenuShareAppMessage(title, desc, shareLink, shareImgUrl);
onMenuShareTimeline(title, desc, shareLink, shareImgUrl);
});
}
function initWeChat(signature, appId,timestamp,noncestr) {
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appId, // 必填,公众号的唯一标识
timestamp: "", // 必填,生成签名的时间戳
nonceStr: "", // 必填,生成签名的随机串
signature:"",//必填,签名
jsApiList: [// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
'checkJsApi',
'onMenuShareTimeline',//-----------------我们这里用了分享朋友圈
'onMenuShareAppMessage',//----------------好友
]
});
}
//分享给朋友
function onMenuShareAppMessage(title, desc, shareLink, imgUrl) {
wx.onMenuShareAppMessage({
title: title,
desc: desc,
link: shareLink,
imgUrl: imgUrl,
trigger: function (res) {
// 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
// alert('用户点击发送给朋友'+JSON.stringify(res));
wechatActionCallback('SHARE_FRIEND', 'CLICK');
},
success: function (res) {
// alert('已分享'+JSON.stringify(res));
wechatActionCallback('SHARE_FRIEND', 'SUCESS');
},
cancel: function (res) {
wechatActionCallback('SHARE_FRIEND', 'CANCEL');
// alert('已取消'+JSON.stringify(res));
},
fail: function (res) {
wechatActionCallback('SHARE_FRIEND', 'FAIL');
// alert(JSON.stringify(res));
}
});
}
//分享到朋友圈
function onMenuShareTimeline(title, desc, shareLink, imgUrl) {
wx.onMenuShareTimeline({
title: title, // 分享标题
link: shareLink,// 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: imgUrl,// 分享图标
desc: desc,
trigger: function (res) {
// 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
// alert('用户点击分享到朋友圈'+JSON.stringify(res));
wechatActionCallback('SHARE_TIME_LINE', 'CLICK');
},
success: function (res) {
// alert('已分享'+JSON.stringify(res));
wechatActionCallback('SHARE_TIME_LINE', 'SUCESS');
},
cancel: function (res) {
// alert('已取消'+JSON.stringify(res));
wechatActionCallback('SHARE_TIME_LINE', 'CANCEL');
},
fail: function (res) {
//
alert(JSON.stringify(res));
wechatActionCallback('SHARE_TIME_LINE', 'FAIL');
}
});
}
2,java后台代码
2.1 控制器
package com.xxx.xxx;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(value = "/weixin")
public class WeiXinController {
@RequestMapping("/sgture.do")
@ResponseBody
public Map<String, Object> sgture(HttpServletRequest request) {
String strUrl=request.getParameter("url");
WinXinEntity wx = WeiXinUnitl.getWinXinEntity(strUrl);
// 将wx的信息到给页面
Map<String, Object> map = new HashMap<String, Object>();
String sgture = WXUnitl.getSignature(wx.getTicket(), wx.getNoncestr(), wx.getTimestamp(), strUrl);
map.put("sgture", sgture.trim());//签名
map.put("timestamp", wx.getTimestamp().trim());//时间戳
map.put("noncestr", wx.getNoncestr().trim());//随即串
map.put("appid","这里写appid");//appID
return map;
}
}
2.2 工具类
这里的AppId,secret,管项目经理要
package com.xxx.xxx;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import net.sf.json.JSONObject;
public class WeiXinUnitl {
public static WinXinEntity getWinXinEntity(String url) {
WinXinEntity wx = new WinXinEntity();
String access_token = getAccessToken();
String ticket = getTicket(access_token);
Map<String, String> ret = Sign.sign(ticket, url);
wx.setTicket(ret.get("jsapi_ticket"));
wx.setSignature(ret.get("signature"));
wx.setNoncestr(ret.get("nonceStr"));
wx.setTimestamp(ret.get("timestamp"));
return wx;
}
// 获取token
private static String getAccessToken() {
String access_token = "";
String grant_type = "client_credential";//获取access_token填写client_credential
String AppId="找你们老大要";//第三方用户唯一凭证
String secret="找你们老大要";//第三方用户唯一凭证密钥,即appsecret
//这个url链接地址和参数皆不能变
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="+grant_type+"&appid="+AppId+"&secret="+secret; //访问链接
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);
JSONObject demoJson = JSONObject.fromObject(message);
access_token = demoJson.getString("access_token");
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return access_token;
}
// 获取ticket
private static 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);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
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);
ticket = demoJson.getString("ticket");
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return ticket;
}
}
2.3 创建一个实体类
package com.xxx.xxx;
public class WinXinEntity {
private String access_token;
private String ticket;
private String noncestr;
private String timestamp;
private String str;
private String signature;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public String getNoncestr() {
return noncestr;
}
public void setNoncestr(String noncestr) {
this.noncestr = noncestr;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
}
2.4 生成签名,随机串,时间戳
package com.xxx.xxx;
import java.util.UUID;
import java.util.Map;
import java.util.HashMap;
import java.util.Formatter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;
public class Sign {
public static Map<String, String> sign(String jsapi_ticket, String url) {
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
// 注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "×tamp=" + timestamp + "&url=" + url;
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature= WXUnitl.getSignature(jsapi_ticket, nonce_str, timestamp, url);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
// 生成签名
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
// 生成nonce_str
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
// 生成timestamp
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
}
2.5 获取签名,随机串
package com.xxx.xxx;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Formatter;
import java.util.logging.Logger;
import org.hibernate.validator.internal.util.logging.LoggerFactory;
public class WXUnitl {
public static String getSignature(String jsapi_ticket, String nonce_str, String timestamp, String url) {
// 注意这里参数名必须全部小写,且必须有序
String string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "×tamp=" + timestamp + "&url="
+ url;
String signature = "";
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return signature;
}
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
}
3.下面开始调试吧
调试之前需要一个web调试工具,没有的可以下载
官方地址:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html