微信公众号网页分享功能开发的示例代码


Posted in Javascript onMay 27, 2020

    现在每天都可以看到很多微信分享的链接上面有网站或者商家的自定义的分享标题,和分享链接的描述及分享出去的图像,例如下面的分享出去的链接:

微信公众号网页分享功能开发的示例代码  

     上面这个是微信的js-SDK页面分享给微信好友在聊天列表中显示的视觉效果。

      微信JS-SDK Demo :这个是微信网页分享出去的标题。

     微信JS-SDK,帮助第三方为用户提供更优质的移动web服务:这个是被分享的这个页面的分享描述。

     微信图标:这个就是自己网站或者自己自定义的图像。

     上面这个是微信官方网页分享出去的定义描述,那么怎样实现自己网站网页的自定义分享的标题,描述及分享出去的显示图片呢,下面就具体的来探讨一下微信网页第三方分享自定的实现方式。

     关于微信网页分享自定义主要有两方面的工作需要我们来做,一是:分享页面的js分享代码的编写,二是:微信分享网页的链接地址签名。

     首先来看一下网页的连接地址签名,这个功能主要是在服务端来时实现。

     第一步:基础数据的准备,需要如下数据信息:

     APPID:微信公众号的id; APP_SECRECT:公众号号的密钥。签名的网站域名(这个建议配置在配置文件中)。

     第二步:微信签名数据的准备:

    appid,secret,url将这三个参数放入map中, 键值为:appid=微信公众号的id,secret=APP_SECRECT,url=网站的域名+网页的请求地址+请求的参数。

代码的实现方式如下:

1. controller层的代码实现: 

@RequestMapping("cover")
   public String identifyCover(HttpServletRequest request, HttpServletResponse response)
	  //微信分享授权开始
    String appId = ;//取项目中配置的公众号id
    String secret = ;//取项目中配置的公众号密钥
    //例如我们有一个分享的链接为:http://test.weixinfwenx.cn/project/fenxiang.do?id=1&name=2;
    //那么domainAddr = http://test.weixinfwenx.cn,这个可以动态的配置在项目里,方便测试环境和生产
    //域名的切换
    String domainAddr = "";//项目中配置的网站的域名
    //这个取的是链接上的参数,例如在上面的这个链接中,id=1&name=2就是我们要动态去的参数,可能有人        
    //会想到,这个两个参数直接写在地址中不是挺简单的为啥还要动态去获取这个参数呢;在这里我们引出了一       
    //个微信二次分享的问题,就是别人转发的链接给你,然后你再转发给别人,在你转发给别人后这个链接的签       
    //名就会失败,为啥呢,因为经过再次转发的链接,微信会自动加上一些自己的参数,这样会导致页面上微信       
    //分享的链接和签名的链接不一致。直接导致自定义的标题和链接描述,显示失败,失败原因是微信默认的在       
    //我们的分享链接上加上了&from=singlemessage。
    String str = request.getQueryString();
    Map<String, String> map = new HashMap<String, String>(); 
    map.put("appid", appId); 
    map.put("secret", secret); 
    String url = domainAddr + "/project/fenxiang.do?"+str; map.put("url", url);
    //这个地址是传给页面使用
    request.setAttribute("fenxurl", url);
    //开始微信分享链接签名
    Map<String, String> params = weixinService.weixinjsIntefaceSign(map);
    request.setAttribute("params", params);
    return "自己的页面";

2.service层的实现代码:

接口:  

public interface weixinService{
	 /**
	  * @Title: weixinjsIntefaceSign
	  * @Description: 微信js接口授权
	  * @param map
	  * @return
	  * @return: Map<String,String>
	  */
 public Map<String,String> weixinjsIntefaceSign(Map<String,String> map);

接口实现类:

public class weixinServiceImpl implements weixinService{
	 public Map<String, String> weixinjsIntefaceSign(Map<String, String> map){
		 //查看缓存数据是否存在
		 String cacheAccess_token = jedis.get("access_token");
		 String cacheTicket = jedis.get("ticket");
		 //取出来为空的话则说明cacheAccess_token缓存过期,重新获取
		 if(null == cacheAccess_token){
			 ///////////////////////////////start
			 //获取cacheAccess_token  
			 //这段代码实际开发过程中要写成一个方法,我这里为了演示方便写在了一起。
			 StringBuffer buffer = new StringBuffer();
			 buffer.append("https://api.weixin.qq.com/cgi-bin/token?");
			 buffer.append("appid="+map.get("appid"));
			 buffer.append("&secret="+map.get("secret"));
			 buffer.append("&grant_type=client_credential");
			 String resultMsg = SendUtils.sendGet(buffer.toString(), "UTF-8");
			 ///////////////////// end
			 
			 JSONObject json = new JSONObject(resultMsg);
			 cacheAccess_token = json.getString("access_token");
			 jedis.set("access_token",cacheAccess_token, "NX", "EX", 3600);//单位是秒
		 }
		 //取出来为空的话则说明cacheTicket缓存过期,重新获取
		 if(null == cacheTicket){
			 ////////////////////////// start
			 ////获得jsapi_ticket
			 StringBuffer buffer = new StringBuffer();
			 buffer.append("https://api.weixin.qq.com/cgi-bin/ticket/getticket?");
			 buffer.append("access_token="+access_token);
			 buffer.append("&type=jsapi");
			 String ticket = SendUtils.sendGet(buffer.toString(), "UTF-8");
			 ///////////////////// end
			 
			 JSONObject json2 = new JSONObject(ticket);	  
			 cacheTicket = json2.getString("ticket");
			 jedis.set("ticket",cacheTicket, "NX", "EX", 3600);//单位是秒	
		 }
		 //生成签名
		 SortedMap<Object,Object> params = new TreeMap<Object,Object>();	    
		 params.put("timestamp", Long.toString(new Date().getTime()/1000));
		 params.put("noncestr", this.CreateNoncestr());
		 params.put("jsapi_ticket",cacheTicket);
		 params.put("url",map.get("url"));//url地址
		 StringBuffer sb = new StringBuffer();
		 Set es = params.entrySet();
		 Iterator it = es.iterator();
		 while(it.hasNext()) {
			 Map.Entry entry = (Map.Entry)it.next();
			 String k = (String)entry.getKey();
			 Object v = entry.getValue();
			 sb.append(k + "=" + v + "&");
		 }
		 String signStr = sb.toString().substring(0, sb.toString().length()-1);
		 String sign = Sha1.getSha1Sign(signStr);//签名	
		 Map<String, String> result = new HashMap<String,String>();
		 result.put("timestamp",(String)params.get("timestamp"));
		 result.put("noncestr", (String)params.get("noncestr"));
		 result.put("signature", sign);
		 result.put("appId",map.get("appid"));
		 return result;
		 
		 return null;
		 
	 }
    private String CreateNoncestr() {
		String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		String res = "";
		for (int i = 0; i < 16; i++) {
			Random rd = new Random();
			res += chars.charAt(rd.nextInt(chars.length() - 1));
		}
		return res;
	}
 }

辅助工具类:

/**
 * 
 * 加密工具类
 *
 */
public class Sha1 {
	 public static String getSha1Sign(String decript) { 
		 try { 
			 MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1"); 
			 try {
				 digest.update(decript.getBytes("UTF-8"));
			 } catch (UnsupportedEncodingException e) {
				 // TODO Auto-generated catch block
				 e.printStackTrace();
			 } 
			 byte messageDigest[] = digest.digest(); 
			 // Create Hex String 
			 StringBuffer hexString = new StringBuffer(); 
			 // 字节数组转换为 十六进制 数 
			 for (int i = 0; i < messageDigest.length; i++) { 
				 String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); 
				 if (shaHex.length() < 2) { 
					 hexString.append(0); 
				 } 
				 hexString.append(shaHex); 
			 } 
			 return hexString.toString(); 
			 
		 } catch (NoSuchAlgorithmException e) { 
			 e.printStackTrace(); 
		 } 
		 return ""; 
	 } 
}

http请求工具类:

/** 
 * http请求工具类
 *
 */
 public class SendUtils {
	 public static String sendGet(String url,String charset){
			//新建客户端
			HttpClient httpclient = new HttpClient();
			GetMethod getMethod = new GetMethod(url);
			httpclient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);
			httpclient.executeMethod(getMethod);
			String responseMsg = getMethod.getResponseBodyAsString();
			return responseMsg;	
	 }
 }

以上是服务器端的微信签名的实现代码,下面介绍一下分享页面中js的编写。

第一步引入微信的js文件:

<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

第二步:  

wx.config({
				debug: false, 
				appId: '${params.appId}',
				timestamp: '${params.timestamp}',
				nonceStr: '${params.noncestr}', 
				signature:'${params.signature}',
				jsApiList: [
		      'onMenuShareTimeline',
		      'onMenuShareAppMessage',
		      'onMenuShareQQ',
			    'onMenuShareWeibo',
			    'onMenuShareQZone' 
				]
			});
     wx.ready(function(){
			wx.checkJsApi({
			  jsApiList: [
			    'onMenuShareTimeline',
			    'onMenuShareAppMessage',
			    'onMenuShareQQ',
			    'onMenuShareWeibo',
			    'onMenuShareQZone'  
			  ]
			});
				wx.checkJsApi({
				  jsApiList: [
				    'onMenuShareTimeline',
				    'onMenuShareAppMessage',
				    'onMenuShareQQ',
				    'onMenuShareWeibo',
				    'onMenuShareQZone'  
				  ]
				});
			/*分享到朋友圈*/
			wx.onMenuShareTimeline({
			 	title: '计划书', // 分享标题
			 	desc: '保险让生活更美好!', // 分享描述
			  link: '${fenxurl}', // 分享链接
			  imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
			  success: function () { 
			    // 用户确认分享后执行的回调函数
			  },
			  cancel: function () { 
			    // 用户取消分享后执行的回调函数
			  }
			});
			/*分享给朋友*/
			wx.onMenuShareAppMessage({
				title: '计划书', // 分享标题
				desc: '保险让生活更美好!', // 分享描述
			  link: '${fenxurl}', // 分享链接
			  imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
			  type: 'link', // 分享类型,music、video或link,不填默认为link
			  dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
			  success: function () { 
			  	// 用户确认分享后执行的回调函数
			  	alert("您已分享");
			  },
			  cancel: function () { 
			  	 // 用户取消分享后执行的回调函数
			  	alert('您已取消分享');
			  }
			});
			wx.onMenuShareQQ({
				title: '计划书', // 分享标题
				desc: '保险让生活更美好!', // 分享描述
			  link: '${fenxurl}', // 分享链接
			  imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
			  success: function () { 
			    // 用户确认分享后执行的回调函数
			  },
			  cancel: function () { 
			    // 用户取消分享后执行的回调函数
			  }
			});
			wx.onMenuShareWeibo({
				title: '计划书', // 分享标题
				desc: '保险让生活更美好!', // 分享描述
			  link: '${fenxurl}', // 分享链接
			  imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
			  success: function () { 
			    // 用户确认分享后执行的回调函数
			  },
			  cancel: function () { 
			    // 用户取消分享后执行的回调函数
			  }
			});
			wx.onMenuShareQZone({
				title: '计划书', // 分享标题
				desc: '保险让生活更美好!', // 分享描述
			  link: '${fenxurl}', // 分享链接
			  imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享图标
			  success: function () { 
			    // 用户确认分享后执行的回调函数
			  },
			  cancel: function () { 
			    // 用户取消分享后执行的回调函数
			  }
			});
		 });

至此整个微信的整个分享开发完成,上面的这些js文件,都必须放在页面上。

到此这篇关于微信公众号网页分享功能开发的示例代码的文章就介绍到这了,更多相关微信公众号网页分享内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
window.location.hash 属性使用说明
Mar 20 Javascript
style、 currentStyle、 runtimeStyle区别分析
Aug 01 Javascript
关于JavaScript定义类和对象的几种方式
Nov 09 Javascript
循环 vs 递归浅谈
Feb 28 Javascript
JQuery的自定义事件代码,触发,绑定简单实例
Aug 01 Javascript
Javascript中arguments对象的详解与使用方法
Oct 04 Javascript
js验证手机号、密码、短信验证码代码工具类
Jun 24 Javascript
Express系列之multer上传的使用
Oct 27 Javascript
关于Angularjs中自定义指令一些有价值的细节和技巧小结
Apr 22 Javascript
JavaScript实现的滚动公告特效【基于jQuery】
Jul 10 jQuery
Vue 实现输入框新增搜索历史记录功能
Oct 15 Javascript
vue中对象数组去重的实现
Feb 06 Javascript
JS字符串补全方法padStart()和padEnd()
May 27 #Javascript
Js生成随机数/随机字符串的方法小结【5种方法】
May 27 #Javascript
JS箭头函数和常规函数之间的区别实例分析【 5 个区别】
May 27 #Javascript
使用JavaScript获取Django模板指定键值数据
May 27 #Javascript
基于Vue CSR的微前端实现方案实践
May 27 #Javascript
Node.js API详解之 vm模块用法实例分析
May 27 #Javascript
jQuery实现鼠标滑动切换图片
May 27 #jQuery
You might like
php生成xml简单实例代码
2009/12/16 PHP
preg_match_all使用心得分享
2014/01/31 PHP
PHP判断用户是否已经登录(跳转到不同页面或者执行不同动作)
2016/09/22 PHP
PHP实现针对日期,月数,天数,周数,小时,分,秒等的加减运算示例【基于strtotime】
2017/04/19 PHP
PHP+Ajax实现的博客文章添加类别功能示例
2018/03/29 PHP
PHP生成zip压缩包的常用方法示例
2019/08/22 PHP
js href的用法
2010/05/13 Javascript
javascript调试说明
2010/06/07 Javascript
关于全局变量和局部变量的那些事
2013/01/11 Javascript
js实现的折叠导航示例
2013/11/29 Javascript
Javascript中的String对象详谈
2014/03/03 Javascript
jquery特效 点击展示与隐藏全文
2015/12/09 Javascript
js类式继承与原型式继承详解
2016/04/07 Javascript
使用Bootstrap框架制作查询页面的界面实例代码
2016/05/27 Javascript
JavaScript学习小结之被嫌弃的eval函数和with语句实例详解
2016/08/01 Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
2016/08/18 Javascript
Javascript中document.referrer隐藏来源的方法
2017/01/16 Javascript
Vue Ajax跨域请求实例详解
2017/06/20 Javascript
小程序Scroll-view上拉滚动刷新数据
2020/06/21 Javascript
jQuery zTree如何改变指定节点文本样式
2020/10/16 jQuery
[05:04]完美世界携手游戏风云打造 卡尔工作室地图界面篇
2013/04/23 DOTA
Python 时间处理datetime实例
2008/09/06 Python
Python使用Srapy框架爬虫模拟登陆并抓取知乎内容
2016/07/02 Python
使用python 爬虫抓站的一些技巧总结
2018/01/10 Python
numpy中的高维数组转置实例
2018/04/17 Python
python使用 __init__初始化操作简单示例
2019/09/26 Python
Django CSRF认证的几种解决方案
2020/03/03 Python
Python文本文件的合并操作方法代码实例
2020/03/31 Python
快速创建 HTML5 Canvas 电信网络拓扑图的示例代码
2018/03/21 HTML / CSS
西班牙香水和化妆品连锁店:Druni
2019/05/05 全球购物
环境科学专业研究生求职信
2013/10/02 职场文书
优秀中学生事迹材料
2014/01/31 职场文书
铁人纪念馆观后感
2015/06/16 职场文书
Javascript中Microtask和Macrotask鲜为人知的知识点
2022/04/02 Javascript
php解析非标准json、非规范json的方式实例
2022/05/10 PHP
python数字图像处理之图像的批量处理
2022/06/28 Python