APP分享到微信的流程(以及二次分享样式问题) | 您所在的位置:网站首页 › 携程行程怎么分享微信好友 › APP分享到微信的流程(以及二次分享样式问题) |
如果要完成微信分享,还是有需要去微信官方开发文档看一下的。附上地址: 微信开发平台 微信公众平台开发文档 自己老年记忆力过段时间肯定会忘记如何去实现这个功能,所以记录一下。 因为自己不是写客户端的(Android、ios),所以前端代码并不能详细记录在这里,可以参考微信开发平台中的说明。后端服务是在客户端提供给我们一个接口的前提下进行开发的。 接口如下: /** * 分享 * type:1:仅分享到通讯2:仅分享到其他3:分享到通讯和其他, * wxTitle:微信分享标题(type==2|3时,必输), * wxDes:微信分享描述(type==2|3时,必输), * wxLink:微信分享分享页面地址(type==2|3时,必输), * wxThump:微信分享 缩略图, * wxType:微信分享类型0:网页分享1:文本分享2:本地图片分享3:网络图片分享, */ function shareMsg(json){ window.SysClientJs.shareMsgTo(JSON.stringify(json)); }ps:参数type是用来表示点击分享后都有哪几个分享选项供用户选择: 1:平台通讯(我们自己应用内的通讯) 2:只分享到微信(没有平台通讯选项) 3:平台通讯和微信都有 一、APP内容分享到微信有了客户端给的方法,实现微信分享功能就比较简单了。 /* * 封装传送的数据 */ var json ={ type:'2', wxTitle:'**银行代销基金产品', wxDes:'我行代销各类基金产品,请点击查看详情', wxLink:$rootScope.AppUrl+'fundListWXShare?ShareId='+data.ShareId }; /* * 调用分享方法 */ $clientUtils.shareMsg(json);到这里微信分享就结束了,wxThump不填,默认选择客户端已经定义的图片,wxType默认为1。 分享后的图片: ps:图片并不是代码里边的基金产品,不过样式是一样的。 好的,终于可以把好东西分享给好友了,但是好友并点不开你的分享。还差一步,你分享的这个东西相当于一个链接,就是参数里边的wxLink。好友点击你分享的内容,就相当于在微信浏览器里边输入了一个地址,然后微信浏览器去服务器获取页面展示给用户。最后一步就是写个页面来响应浏览器的请求。 二、微信二次分享问题问题复现流程:分享给好友->好友打开看了看感觉还不错就想分享给他的好友->点击微信浏览器右上角的三个点 标题变了,摘要变了,图片也没了...... 有问题就只能解决,之前试过WeixinJSBridge接口,但是没有效果,通过百度了解到微信为了整顿"诱导分享"的行为,关闭了WeixinJSBridge。 经过百度、看开发文档,总算找到了解决方法。 首先,你得有一个已经认证的微信公众号(企业公众号),没有是不行滴~。 要准备的东西: 1.APPID、appsecret(在微信公众号 开发->基本设置 能看到) 2.公众号要设置安全域名(在 微信公众号 设置->公众号设置 -> 功能设置 -> JS接口安全域名) 3.IP地址白名单 设置->安全中心->IP白名单(IP地址就是服务器地址,没有这个白名单获取token时 会报IP地址非法。) 下面开始撸代码: 1).从微信获取token向微信给定的url(https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET)发GET请求,获取token和token的有效期,获取token只需要替换APPID和APPSECRET,grant_type的值不变。 /* accessToken 静态全局变量 保存上次获取的token * tokenExpireTime 静态的全局变量 保存上次获取token的有效期 * getTokenTime 静态的全局变量 保存上次获取token的时间 */ if(accessToken==null||("").equals(accessToken)||(now - getTokenTime > tokenExpireTime*1000)){ Map tokenInfo = getAccessToken(); if(tokenInfo != null){ accessToken = (String) tokenInfo.get("access_token"); tokenExpireTime = Long.parseLong(tokenInfo.get("expires_in")+""); getTokenTime = System.currentTimeMillis(); }else{ logger.info("get token is failure!"); } } private Map getAccessToken(){ String requestUrl = accessTokenUrl.replace("APPID",appId).replace("APPSECRET",appSecret); Map result = HttpUtil.doGet(requestUrl);//向微信发送get请求 return result ; }ps:token有每天的获取次数和获取频率,如果频繁获取将会触发限制。所以token要在本地缓存,上边的代码缓存简单的用static来存储,严格来说应该存在数据库,如果生产上有多台服务器,就必须要存在数据库了。 2).从微信获取ticket跟获取token有一点不同,token是获取ticket的参数,最后我们只需要ticket。url如下:(https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi)只需要把ACCESS_TOKEN(就是我们第一步获取的token)替换就OK。 if(jsApiTicket==null||("").equals(jsApiTicket)||(now - getTiketTime > ticketExpireTime*1000)){ Map ticketInfo = getJsApiTicket(); if(ticketInfo!=null){ jsApiTicket = (String) ticketInfo.get("ticket"); ticketExpireTime = Long.parseLong(ticketInfo.get("expires_in")+""); getTiketTime = System.currentTimeMillis(); }else{ logger.info("get ticket is failure!"); } } @SuppressWarnings("rawtypes") private Map getJsApiTicket(){ String requestUrl = apiTicketUrl.replace("ACCESS_TOKEN", accessToken); Map result = HttpUtil.doGet(requestUrl); return result; } 3).生成签名下图是微信开发文档的签名算法,开发文档中还有微信给的简单示例(java、php...)。 实现代码: public Map makeWXTicket(String jsApiTicket, String url) { Map ret = new HashMap(); String nonceStr = createNonceStr(); String timestamp = createTimestamp(); String string1; String signature = ""; string1 = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url; try{ MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(string1.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); }catch (Exception e){ logger.error("WeChatController.makeWXTicket=====Start"); logger.error(e.getMessage(),e); logger.error("WeChatController.makeWXTicket=====End"); } ret.put("url", url); ret.put("jsapi_ticket", jsApiTicket); ret.put("nonceStr", nonceStr); ret.put("timestamp", timestamp); ret.put("signature", signature); ret.put("appid", appId); 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; } private static String createNonceStr() { return UUID.randomUUID().toString(); } private static String createTimestamp() { return Long.toString(System.currentTimeMillis() / 1000); } 4).前端校验data是后端传过来的数据:包含appid、时间戳、随机字符串、签名、ticket、url。 wx.config({ debug: false, appId: data.appid, timestamp: data.timestamp, nonceStr: data.nonceStr, signature: data.signature, jsApiList: [//需要用到的接口 'checkJsApi', 'onMenuShareTimeline',//分享到朋友圈的接口 'onMenuShareAppMessage'//分享给朋友的接口 ] });如果验证成功,debug模式下会提示config:ok。一般情况下,不OK一般是因为url的问题。url的值就是分享微信时wxLink的值去掉#号后边的内容。一般url的取值在js中取: url = location.href.split('#')[0].toString();传到后端进行签名。这个url必须包含在js接口安全域名内。 5).分享到朋友圈、好友分享到朋友圈、好友这两个接口只是众多接口中比较常用的两个。还有分享到qq、微博等接口。 wx.ready(function () { wx.checkJsApi({//可要可不要,功能只是校验下都支持哪些接口 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage'], success:function(res){ } }); wx.onMenuShareTimeline({ title: title,//自定义的标题 link: link,//自定义的链接 imgUrl: $rootScope.rootUrl+'share/assets/logo.jpg',//自定义的图片 trigger: function (res) { }, success: function (res) { }, cancel: function (res) { }, fail: function (res) { } }); wx.onMenuShareAppMessage({ title: title, desc: desc, link: link, imgUrl: $rootScope.rootUrl+'share/assets/logo.jpg', type: 'link', dataUrl: '', success: function () { }, cancel: function () { } }); wx.error(function (res) { }); });ok,效果图如下: |
CopyRight 2018-2019 实验室设备网 版权所有 |