第一部分:微信JS-SDK介绍

微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。

通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

本次的内容:

实现:分享到朋友圈,qq,qq空间,微信朋友的功能。

基础接口

判断当前客户端版本是否支持指定JS接口

  1. wx.checkJsApi({
  2. jsApiList: ['chooseImage'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
  3. success: function(res) {
  4. // 以键值对的形式返回,可用的api值true,不可用为false
  5. // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
  6. }
  7. });

备注:checkJsApi接口是客户端6.0.2新引入的一个预留接口,第一期开放的接口均可不使用checkJsApi来检测。

获取“分享到朋友圈”按钮点击状态及自定义分享内容接口

  1. wx.onMenuShareTimeline({
  2. title: '', // 分享标题
  3. link: '', // 分享链接
  4. imgUrl: '', // 分享图标
  5. success: function () {
  6. // 用户确认分享后执行的回调函数
  7. },
  8. cancel: function () {
  9. // 用户取消分享后执行的回调函数
  10. }
  11. });

获取“分享给朋友”按钮点击状态及自定义分享内容接口

  1. wx.onMenuShareAppMessage({
  2. title: '', // 分享标题
  3. desc: '', // 分享描述
  4. link: '', // 分享链接
  5. imgUrl: '', // 分享图标
  6. type: '', // 分享类型,music、video或link,不填默认为link
  7. dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
  8. success: function () {
  9. // 用户确认分享后执行的回调函数
  10. },
  11. cancel: function () {
  12. // 用户取消分享后执行的回调函数
  13. }
  14. });

获取“分享到QQ”按钮点击状态及自定义分享内容接口

  1. wx.onMenuShareQQ({
  2. title: '', // 分享标题
  3. desc: '', // 分享描述
  4. link: '', // 分享链接
  5. imgUrl: '', // 分享图标
  6. success: function () {
  7. // 用户确认分享后执行的回调函数
  8. },
  9. cancel: function () {
  10. // 用户取消分享后执行的回调函数
  11. }
  12. });

获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口

  1. wx.onMenuShareWeibo({
  2. title: '', // 分享标题
  3. desc: '', // 分享描述
  4. link: '', // 分享链接
  5. imgUrl: '', // 分享图标
  6. success: function () {
  7. // 用户确认分享后执行的回调函数
  8. },
  9. cancel: function () {
  10. // 用户取消分享后执行的回调函数
  11. }
  12. });

获取“分享到QQ空间”按钮点击状态及自定义分享内容接口

  1. wx.onMenuShareQZone({
  2. title: '', // 分享标题
  3. desc: '', // 分享描述
  4. link: '', // 分享链接
  5. imgUrl: '', // 分享图标
  6. success: function () {
  7. // 用户确认分享后执行的回调函数
  8. },
  9. cancel: function () {
  10. // 用户取消分享后执行的回调函数
  11. }
  12. });

附录2-所有JS接口列表

版本1.0.0接口

  • onMenuShareTimeline
  • onMenuShareAppMessage
  • onMenuShareQQ
  • onMenuShareWeibo
  • onMenuShareQZone

附录3-所有菜单项列表

  • 发送给朋友: "menuItem:share:appMessage"
  • 分享到朋友圈: "menuItem:share:timeline"
  • 分享到QQ: "menuItem:share:qq"
  • 分享到Weibo: "menuItem:share:weiboApp"
  • 收藏: "menuItem:favorite"
  • 分享到FB: "menuItem:share:facebook"
  • 分享到 QQ 空间/menuItem:share:QZone

详细的可以参照微信官方的介绍: 微信JS-SDK说明文档

第二部分:分享方法的实现。

那么,我们如何来实现这个分享内容呢?

JSSDK使用步骤

步骤一:绑定域名

1. 先登录微信公众平台 ,登录后可在“开发者中心”查看对应的接口权限。

说明了有这个分享的权限。

2.  进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

js域名,一般不用http这样的开头。

步骤二:引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js

请注意,如果你的页面启用了https,务必引入 https://res.wx.qq.com/open/js/jweixin-1.0.0.js ,否则将无法在iOS9.0以上系统中成功使用JSSDK

如需使用摇一摇周边功能,请引入 jweixin-1.1.0.js

备注:支持使用 AMD/CMD 标准模块加载方法加载

  1. <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

步骤三:通过config接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

  1. wx.config({
  2. debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  3. appId: '', // 必填,公众号的唯一标识
  4. timestamp: , // 必填,生成签名的时间戳
  5. nonceStr: '', // 必填,生成签名的随机串
  6. signature: '',// 必填,签名,见附录1
  7. jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
  8. });

注意,我这里只是动态获取,并没有做缓存,如果有需要的同学,需要做一些缓存。

如何获取以上的参数呢?

  1. package com.souvc.weixin.util;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.io.OutputStream;
  7. import java.io.UnsupportedEncodingException;
  8. import java.net.ConnectException;
  9. import java.net.URL;
  10. import java.security.MessageDigest;
  11. import java.security.NoSuchAlgorithmException;
  12. import java.util.Formatter;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. import java.util.UUID;
  16.  
  17. import javax.net.ssl.HttpsURLConnection;
  18. import javax.net.ssl.SSLContext;
  19. import javax.net.ssl.SSLSocketFactory;
  20. import javax.net.ssl.TrustManager;
  21. import javax.servlet.http.HttpServletRequest;
  22.  
  23. import net.sf.json.JSONObject;
  24.  
  25. public class WeixinUtil {
  26.  
  27. /**
  28. * 方法名:httpRequest</br>
  29. * 详述:发送http请求</br>
  30. * 开发人员:souvc </br>
  31. * 创建时间:2016-1-5 </br>
  32. * @param requestUrl
  33. * @param requestMethod
  34. * @param outputStr
  35. * @return 说明返回值含义
  36. * @throws 说明发生此异常的条件
  37. */
  38. public static JSONObject httpRequest(String requestUrl,String requestMethod, String outputStr) {
  39. JSONObject jsonObject = null;
  40. StringBuffer buffer = new StringBuffer();
  41. try {
  42. TrustManager[] tm = { new MyX509TrustManager() };
  43. SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
  44. sslContext.init(null, tm, new java.security.SecureRandom());
  45. SSLSocketFactory ssf = sslContext.getSocketFactory();
  46. URL url = new URL(requestUrl);
  47. HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
  48. httpUrlConn.setSSLSocketFactory(ssf);
  49. httpUrlConn.setDoOutput(true);
  50. httpUrlConn.setDoInput(true);
  51. httpUrlConn.setUseCaches(false);
  52. httpUrlConn.setRequestMethod(requestMethod);
  53. if ("GET".equalsIgnoreCase(requestMethod))
  54. httpUrlConn.connect();
  55. if (null != outputStr) {
  56. OutputStream outputStream = httpUrlConn.getOutputStream();
  57. outputStream.write(outputStr.getBytes("UTF-8"));
  58. outputStream.close();
  59. }
  60. InputStream inputStream = httpUrlConn.getInputStream();
  61. InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
  62. BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
  63. String str = null;
  64. while ((str = bufferedReader.readLine()) != null) {
  65. buffer.append(str);
  66. }
  67. bufferedReader.close();
  68. inputStreamReader.close();
  69. inputStream.close();
  70. inputStream = null;
  71. httpUrlConn.disconnect();
  72. jsonObject = JSONObject.fromObject(buffer.toString());
  73. } catch (ConnectException ce) {
  74. ce.printStackTrace();
  75. } catch (Exception e) {
  76. e.printStackTrace();
  77. }
  78. return jsonObject;
  79. }
  80.  
  81. /**
  82. * 方法名:getWxConfig</br>
  83. * 详述:获取微信的配置信息 </br>
  84. * 开发人员:souvc </br>
  85. * 创建时间:2016-1-5 </br>
  86. * @param request
  87. * @return 说明返回值含义
  88. * @throws 说明发生此异常的条件
  89. */
  90. public static Map<String, Object> getWxConfig(HttpServletRequest request) {
  91. Map<String, Object> ret = new HashMap<String, Object>();
  92.  
  93. String appId = "xxxx"; // 必填,公众号的唯一标识
  94. String secret = "xxxx";
  95.  
  96. String requestUrl = request.getRequestURL().toString();
  97. String access_token = "";
  98. String jsapi_ticket = "";
  99. String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成签名的时间戳
  100. String nonceStr = UUID.randomUUID().toString(); // 必填,生成签名的随机串
  101. String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId + "&secret=" + secret;
  102.  
  103. JSONObject json = WeixinUtil.httpRequest(url, "GET", null);
  104.  
  105. if (json != null) {
  106. //要注意,access_token需要缓存
  107. access_token = json.getString("access_token");
  108.  
  109. url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token + "&type=jsapi";
  110. json = WeixinUtil.httpRequest(url, "GET", null);
  111. if (json != null) {
  112. jsapi_ticket = json.getString("ticket");
  113. }
  114. }
  115. String signature = "";
  116. // 注意这里参数名必须全部小写,且必须有序
  117. String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "&timestamp=" + timestamp + "&url=" + requestUrl;
  118. try {
  119. MessageDigest crypt = MessageDigest.getInstance("SHA-1");
  120. crypt.reset();
  121. crypt.update(sign.getBytes("UTF-8"));
  122. signature = byteToHex(crypt.digest());
  123. } catch (NoSuchAlgorithmException e) {
  124. e.printStackTrace();
  125. } catch (UnsupportedEncodingException e) {
  126. e.printStackTrace();
  127. }
  128. ret.put("appId", appId);
  129. ret.put("timestamp", timestamp);
  130. ret.put("nonceStr", nonceStr);
  131. ret.put("signature", signature);
  132. return ret;
  133. }
  134.  
  135. /**
  136. * 方法名:byteToHex</br>
  137. * 详述:字符串加密辅助方法 </br>
  138. * 开发人员:souvc </br>
  139. * 创建时间:2016-1-5 </br>
  140. * @param hash
  141. * @return 说明返回值含义
  142. * @throws 说明发生此异常的条件
  143. */
  144. private static String byteToHex(final byte[] hash) {
  145. Formatter formatter = new Formatter();
  146. for (byte b : hash) {
  147. formatter.format("%02x", b);
  148. }
  149. String result = formatter.toString();
  150. formatter.close();
  151. return result;
  152.  
  153. }
  154. }

注意:以上需要替换成自己的appid和secret 。

步骤四:通过ready接口处理成功验证

  1. wx.ready(function(){
  2.  
  3. // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
  4. });

根据以上的步骤,我们写了一个页面:

  1. <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
  2. <%@page language="java" import="com.souvc.weixin.util.WeixinUtil" %>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  7. <title>欢迎访问搜投网 www.souvc.com </title>
  8. <%
  9. Map<String,Object> ret = new HashMap<String,Object> ();
  10. ret=WeixinUtil.getWxConfig(request);
  11. request.setAttribute("appId", ret.get("appId"));
  12. request.setAttribute("timestamp", ret.get("timestamp"));
  13. request.setAttribute("nonceStr", ret.get("nonceStr"));
  14. request.setAttribute("signature", ret.get("signature"));
  15. %>
  16. </head>
  17. <body>
  18.  
  19. 欢迎访问搜投网!
  20.  
  21. </body>
  22.  
  23. <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
  24. <script type="text/javascript">
  25.  
  26. // 微信信息的以及调用的配置
  27. wx.config({
  28. debug: false,
  29. appId: '${appId}',
  30. timestamp: '${timestamp}',
  31. nonceStr: '${nonceStr}',
  32. signature: '${signature}',
  33. jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone']
  34. });
  35.  
  36. wx.ready(function(){
  37. // 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
  38. wx.onMenuShareTimeline({
  39. title: '第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息', // 分享标题
  40. link:"http://www.cnblogs.com/liuhongfeng/p/5099149.html",
  41. imgUrl: "http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_1442809977405.jpg" // 分享图标
  42. });
  43. // 获取“分享给朋友”按钮点击状态及自定义分享内容接口
  44. wx.onMenuShareAppMessage({
  45. title: '第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息', // 分享标题
  46. desc: "第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息", // 分享描述
  47. link:"http://www.cnblogs.com/liuhongfeng/p/5057167.html",
  48. imgUrl: "http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_QQ%E5%9B%BE%E7%89%8720151118180508.png", // 分享图标
  49. type: 'link', // 分享类型,music、video或link,不填默认为link
  50. });
  51.  
  52. //获取“分享到QQ”按钮点击状态及自定义分享内容接口
  53. wx.onMenuShareQQ({
  54. title: '第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单', // 分享标题
  55. desc: '第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单', // 分享描述
  56. link: 'http://www.cnblogs.com/liuhongfeng/p/4857312.html', // 分享链接
  57. imgUrl: 'http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_qrcode_for_gh_228cd30523bc_258.jpg', // 分享图标
  58. success: function () {
  59. // 用户确认分享后执行的回调函数
  60. },
  61. cancel: function () {
  62. // 用户取消分享后执行的回调函数
  63. }
  64. });
  65.  
  66. //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口
  67. wx.onMenuShareWeibo({
  68. title: '分享到腾讯微博标题', // 分享标题
  69. desc: '分享到腾讯微博描述', // 分享描述
  70. link: 'http://www.cnblogs.com/liuhongfeng/p/4857312.html', // 分享链接
  71. imgUrl: 'http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_qrcode_for_gh_228cd30523bc_258.jpg', // 分享图标
  72. success: function () {
  73. // 用户确认分享后执行的回调函数
  74. },
  75. cancel: function () {
  76. // 用户取消分享后执行的回调函数
  77. }
  78. });
  79.  
  80. //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口
  81. wx.onMenuShareQZone({
  82. title: '分享到QQ空间标题', // 分享标题
  83. desc: '分享到QQ空间描述', // 分享描述
  84. link: 'http://www.cnblogs.com/liuhongfeng/p/4857312.html', // 分享链接
  85. imgUrl: 'http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_qrcode_for_gh_228cd30523bc_258.jpg', // 分享图标
  86. success: function () {
  87. // 用户确认分享后执行的回调函数
  88. },
  89. cancel: function () {
  90. // 用户取消分享后执行的回调函数
  91. }
  92. });
  93.  
  94. });
  95. </script>
  96.  
  97. </html>

步骤五: 部署到服务器。然后访问到这个页面,用微信扫一扫。然后分享到我们设定的接口。

效果如下:

发给微信朋友的效果:

分享到朋友圈的效果:

分享到qq空间的效果:

分享给朋友的效果:

恭喜你,配置成功!!

其他文章关联:

第一篇:微信公众平台开发实战Java版之了解微信公众平台基础知识以及资料准备

第二篇 :微信公众平台开发实战Java版之开启开发者模式,接入微信公众平台开发

第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装

第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理

第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token

第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单

第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息

第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息

第九篇 :微信公众平台开发实战Java版之如何实现自定义分享内容

其他:Web开发须知:URL编码与解码

第九篇 :微信公众平台开发实战Java版之如何实现自定义分享内容的更多相关文章

  1. 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息

    第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...

  2. 第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息

    在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同). 公众号可通过本接口来根据O ...

  3. 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单

    我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...

  4. 第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token

    一.access_token简介 为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台 开放了许多接口,包括自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等, 开 ...

  5. 第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理

    温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发 第三篇 :微信公众 ...

  6. 第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装

    微信服务器和第三方服务器之间究竟是通过什么方式进行对话的? 下面,我们先看下图: 其实我们可以简单的理解: (1)首先,用户向微信服务器发送消息: (2)微信服务器接收到用户的消息处理之后,通过开发者 ...

  7. 第二篇 :微信公众平台开发实战Java版之开启开发者模式,接入微信公众平台开发

    第一部分:微信公众号对接的基本介绍 一.填写服务器配置信息的介绍 登录微信公众平台官网后,进入到公众平台后台管理页面. 选择 公众号基本设置->基本配置 ,点击“修改配置”按钮,填写服务器地址( ...

  8. 第一篇:微信公众平台开发实战Java版之了解微信公众平台基础知识以及资料准备

    相信很多人或多或少听说了微信公众平台的火热.但是开发还是有一点门槛,鉴于挺多朋友问我怎么开发,问多了,自己平时也进行以下总结.所以下面给大家分享一下我的经验: 微信公众号是什么? 官网的介绍:再小的个 ...

  9. 微信公众平台开发实战Java版之如何网页授权获取用户基本信息

    第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...

随机推荐

  1. Spring基础—— SpEL

    一.SpEL:Spring 表达式语言,在使用的时候类似于 EL 表达式,但是需要注意的是,SpEL 使用在 Spring Config 文件中. 二.格式:使用 #{} 作为界定符,所有在大括号中的 ...

  2. 构建之法 第6~7章读后感和对Scrum的理解

    第六章-敏捷流程 第六章主要详细介绍了敏捷流程,在软件工程范畴里,“敏捷流程”是一系列价值观和方法论的集合.这一章以敏捷流程的Scrum方法论而展开,而敏捷流程的精髓就是在于快速的交付. 敏捷开发的流 ...

  3. C#字符串的恒定性

    string str1="aa"; string str2="aa"; str1,str2,变量所指向的堆空间的地址是一样的.栈空间的内容是不一样的. //ne ...

  4. HTML常用符号

    HTML转义符号 HTML常用符号: 显示一个空格    < 小于 < <> 大于 > >& &符号 & &" 双引号 & ...

  5. 自己通过Cygwin编译的windows下的redis3.2.6

    采用方法:https://my.oschina.net/maxid/blog/186506 方法中在3.2.6未找到src/redis.h文件 未修改 方法中 /deps/hiredis/net.c ...

  6. 用stimulsoft Reports报表工具制作简单报表的过程

    这是在数据库sql server中People表的数据

  7. sql 去重

    ;WITH CETAS (SELECT *, ROW_NUMBER() OVER (PARTITION BY SearchTask_PKID ORDER BY SearchTask_PKID) Row ...

  8. Plug-in 'org.eclipse.cdt.ui' contributed an invalid Menu Extension

    终于在mac上配置了最新的eclipse和adt(Win和Mac oxs通用),然后就Error Log报这种错误,运行了hello word,没有影响,但是依旧有这种错误! 记录下错误: eclip ...

  9. js填写银行卡号,每隔4位数字加一个空格

    1.原生js写法 !function () { document.getElementById('bankCard').onkeyup = function (event) { var v = thi ...

  10. MSCRM 仪表盘 控件 数量 更改(Change the maximum no. of controls on MSCRM Dashboards )

    The maximum number of controls allowed on MSCRM dashboards are 6. You cannot put the more than 6 gra ...