要想自定义分享的link、title、desc、imgUrl(分享卡片缩略图)就得集成JSSDK做自定义分享。
准备阶段
第一步要先配置安全域名:
开发阶段可以将测试服和正式服的域名都配进去。

没配置的话点击设置---公众号设置---功能设置进入设置界面:

注意:域名前面不用加协议名称,还有域名服务器根目录下要上传公众号提供的文件(配置的每个域名服务器都要上传哦):MP_verify_qoTb3e9VQBlFWzcn.txt
然后没问题的话点保存,安全域名就配好了。
第二步配置IP白名单
微信公众平台出于安全考虑,根据appId和appSecret去获取access_token的时候,只允许白名单的ip去请求获取access_token的接口。配置的地方在
设置---公众号设置---IP白名单里设置,多个ip用回车间隔。

记得将测试、线上的接口部署的服务器的ip都配置进去。
第三步提交公众号认证:
要确认公众号是认证过的,没认证的话,没法拿到分享按钮的点击状态以及自定义分享内容
第四步在页面里引入微信提供的js文件
如下js文件:http://res.wx.qq.com/open/js/jweixin-1.2.0.js
以上准备工作都做好后,就可以开始使用JSSDK了。
开发阶段
使用自定义分享的步骤是:
一:先在后台通过appId和secret去获取access_token(有效期是2小时,记得缓存起来)。
二:拿到access_token之后,去获取JsApiTicket(有效期是2小时,以下简称ticket)。
三:拿到ticket之后根据ticket、分享的url、随机字符串noncestr、时间戳timestamp去生成签名signature、并将signature及noncestr、timestamp、appid返回给前端去初始化wx.config作权限验证。
生成签名的算法文档:
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
签名校验工具:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
四:接下来就可以 通过ready接口处理成功验证自定义分享内容及拿到分享的回调(成功或者取消分享)
Java代码如下:
1. import java.util.HashMap;
2. import java.util.Map;
3. import java.util.UUID;
4. import javax.servlet.http.HttpServletRequest;
5. import javax.servlet.http.HttpServletResponse;
6. import net.sf.json.JSONObject;
7. import net.sinolbs.base.reqJson.ReqJson;
8. import net.sinolbs.base.utils.EncryptionUtil;
9. import net.sinolbs.base.utils.JedisUtil;
10. import net.sinolbs.base.utils.StringUtil;
11. import net.sinolbs.ycd.BaseApi;
12. import net.sinolbs.ycd.biz.circle.CircleBiz;
13. import net.sinolbs.ycd.entity.circle.Circle;
14. import net.sinolbs.ycd.util.HttpUtil;
15. import org.springframework.beans.factory.annotation.Autowired;
16. import org.springframework.stereotype.Controller;
17. import org.springframework.web.bind.annotation.RequestMapping;
18. /**
19. * 微信分享api
20. */
21. @Controller
22. @RequestMapping(value = "/weiChat")
23. public class WechatApi extends BaseApi{
24. /**
25. *
26. */
27. private static final long serialVersionUID = -4376551313752755646L;
28. private static String appid="你的公众号id";
29. private static String secret="你的公众号的密钥";
30. /**
31. * 获取config初始化参数
32. * @return
33. */
34. @RequestMapping(value = "/getJsApiTicket.json")
35. public void getJsApiTicket(String link,HttpServletRequest request,HttpServletResponse response) {
36. String accessToken=getAccessToken();
37. String jsApiTicket=getJsApiTicket(accessToken);
38. Map<String, String> map = makeWXTicket(jsApiTicket,link);
39. apiData(request, response, ReqJson.ok(map));
40. return ;
41. }
42. @RequestMapping(value = "/getAccessToken.json")
43. public void getAccessToken(HttpServletRequest request,HttpServletResponse response) {
44. String accessToken=getAccessToken();
45. apiData(request, response, ReqJson.ok(accessToken));
46. return ;
47. }
48. /**
49. * 获取access_token
50. * @return
51. */
52. private String getAccessToken(){
53. //从缓存里去获取token
54. "weixinAccessToken");
55. if(StringUtil.isBlank(weixinAccessToken)){
56. String appId=appid;
57. String appSecret=secret;
58. "https://api.weixin.qq.com/cgi-bin/token";
59. "grant_type=client_credential&appid="+appId+"&secret="+appSecret);
60. JSONObject json=JSONObject.fromObject(returnData);
61. if(json.containsKey("access_token")){
62. if(json.get("access_token")!=null&&!json.get("access_token").equals("")){
63. "access_token").toString();
64. "weixinAccessToken",weixinAccessToken, 7200);
65. }
66. }
67. }
68. return weixinAccessToken;
69. }
70.
71. /**
72. * 获取ticket
73. * @return
74. */
75. private String getJsApiTicket(String accessToken){
76. //从缓存里去获取jsApiTicket
77. "jsApiTicket");
78. if (StringUtil.isBlank(jsApiTicket)) {
79. "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
80. "access_token="+accessToken+"&type=jsapi");
81. JSONObject json = JSONObject.fromObject(result);
82. if (json.containsKey("ticket")) {
83. if (json.get("ticket") != null
84. "ticket").equals("")) {
85. "ticket").toString();
86. "jsApiTicket", jsApiTicket, 7200);
87. }
88. }
89. }
90. return jsApiTicket;
91. }
92. //生成微信权限验证的参数
93. public static Map<String, String> makeWXTicket(String jsApiTicket, String url) {
94. new HashMap<String, String>();
95. String nonceStr = createNonceStr();
96. String timestamp = createTimestamp();
97. String string1;
98. "";
99. //注意这里参数名必须全部小写,且必须有序
100. "jsapi_ticket=" + jsApiTicket +
101. "&noncestr=" + nonceStr +
102. "×tamp=" + timestamp +
103. "&url=" + url;
104. try
105. {
106. signature = EncryptionUtil.encodeBySHA1(string1);
107. }
108. catch (Exception e)
109. {
110. e.printStackTrace();
111. }
112. "url", url);
113. "nonceStr", nonceStr);
114. "timestamp", timestamp);
115. "signature", signature);
116. "appid", appid);
117. return ret;
118. }
119.
120. //生成随机字符串
121. private static String createNonceStr() {
122. return UUID.randomUUID().toString();
123. }
124. //生成时间戳
125. private static String createTimestamp() {
126. return Long.toString(System.currentTimeMillis() / 1000);
127. }
页面js代码如下:
1. $.ajax({
2. "/weiChat/getJsApiTicket.json",
3. true,
4. "GET",
5. "json",
6. true,
7. data: {
8. "link": location.href.split("#")[0]
9. },
10. function(data) {
11. wx.config({
12. false,
13. appId: data.info.appid,
14. timestamp: data.info.timestamp,
15. nonceStr: data.info.nonceStr,
16. signature: data.info.signature,
17. 'onMenuShareAppMessage', 'onMenuShareTimeline', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone']
18. });
19.
20. //--
21. function() {
22. wx.checkJsApi({
23. jsApiList: [
24. 'onMenuShareAppMessage', 'onMenuShareTimeline', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone'
25. ],
26. function(res) {
27.
28. }
29. });
30. //分享到朋友圈
31. wx.onMenuShareTimeline({
32. title: data.info.title,
33. desc: data.info.title,
34. "#")[0],
35. imgUrl: data.info.imgUrl,
36. function() {
37. //alert("分享成功!")
38. // 用户确认分享后执行的回调函数
39. },
40. function() {
41. //alert("取消分享!")
42. // 用户取消分享后执行的回调函数
43. }
44. });
45. //分享朋友
46. wx.onMenuShareAppMessage({
47. title: data.info.title,
48. desc: data.info.title,
49. "#")[0],
50. imgUrl: data.info.imgUrl
51. });
52. //分享到QQ
53. wx.onMenuShareQQ({
54. title: data.info.title,
55. desc: data.info.title,
56. "#")[0],
57. imgUrl: data.info.imgUrl
58. });
59. //分享到腾讯微博
60. wx.onMenuShareWeibo({
61. title: data.info.title,
62. desc: data.info.title,
63. "#")[0],
64. imgUrl: data.info.imgUrl
65. });
66. //分享到QQ空间
67. wx.onMenuShareQZone({
68. title: data.info.title,
69. desc: data.info.title,
70. "#")[0],
71. imgUrl: data.info.imgUrl
72. });
73. });
74. ///---
75.
76. },
77. function() {
78. "二次分享错误!");
79. }
80. });
















