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。

分享后的图片:

APP分享到微信的流程(以及二次分享样式问题)_第1张图片

ps:图片并不是代码里边的基金产品,不过样式是一样的。

好的,终于可以把好东西分享给好友了,但是好友并点不开你的分享。还差一步,你分享的这个东西相当于一个链接,就是参数里边的wxLink。好友点击你分享的内容,就相当于在微信浏览器里边输入了一个地址,然后微信浏览器去服务器获取页面展示给用户。最后一步就是写个页面来响应浏览器的请求。

二、微信二次分享问题

问题复现流程:分享给好友->好友打开看了看感觉还不错就想分享给他的好友->点击微信浏览器右上角的三个点  APP分享到微信的流程(以及二次分享样式问题)_第2张图片,->选择发送给朋友 APP分享到微信的流程(以及二次分享样式问题)_第3张图片,ok  结果发现变样了(如下图)。

APP分享到微信的流程(以及二次分享样式问题)_第4张图片

标题变了,摘要变了,图片也没了......

有问题就只能解决,之前试过WeixinJSBridge接口,但是没有效果,通过百度了解到微信为了整顿"诱导分享"的行为,关闭了WeixinJSBridge。

经过百度、看开发文档,总算找到了解决方法。

首先,你得有一个已经认证的微信公众号(企业公众号),没有是不行滴~。

要准备的东西:

1.APPID、appsecret(在微信公众号 开发->基本设置 能看到)

APP分享到微信的流程(以及二次分享样式问题)_第5张图片

2.公众号要设置安全域名(在 微信公众号 设置->公众号设置 -> 功能设置 -> JS接口安全域名)

APP分享到微信的流程(以及二次分享样式问题)_第6张图片

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...)。

APP分享到微信的流程(以及二次分享样式问题)_第7张图片

实现代码:

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,效果图如下:

APP分享到微信的流程(以及二次分享样式问题)_第8张图片


OK,问题到此,就解决完了。可以尽情分享给好友了。

你可能感兴趣的:(APP分享到微信的流程(以及二次分享样式问题))