要想自定义分享的link、title、desc、imgUrl(分享卡片缩略图)就得集成JSSDK做自定义分享。

准备阶段

第一步要先配置安全域名:

开发阶段可以将测试服和正式服的域名都配进去。

微信分享swift_公众号

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

微信分享swift_公众号_02

注意:域名前面不用加协议名称,还有域名服务器根目录下要上传公众号提供的文件(配置的每个域名服务器都要上传哦):MP_verify_qoTb3e9VQBlFWzcn.txt

然后没问题的话点保存,安全域名就配好了。

第二步配置IP白名单

微信公众平台出于安全考虑,根据appId和appSecret去获取access_token的时候,只允许白名单的ip去请求获取access_token的接口。配置的地方在

设置---公众号设置---IP白名单里设置,多个ip用回车间隔。

微信分享swift_公众号_03

记得将测试、线上的接口部署的服务器的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.     });