微信分享

来源:互联网 发布:电影级别剪辑软件 编辑:程序博客网 时间:2024/05/22 05:48

本文转自;https://m.baidu.com/from=1017188c/bd_page_type=1/ssid=0/uid=0/pu=usm%401%2Csz%40320_1001%2Cta%40iphone_2_5.1_3_537/baiduid=FE6FD37447D026F80CDF051570BCDDD9/w=50_10_/t=iphone/l=3/tc?ref=www_iphone&lid=12786222195224295370&order=2&fm=alop&tj=www_normal_2_50_10_title&vit=osres&m=8&srd=1&cltj=cloud_title&asres=1&nt=wnor&title=js-sdk%E6%8E%A2%E7%B4%A2%E4%B9%8B%E5%BE%AE%E4%BF%A1%E7%BD%91%E9%A1%B5%E5%88%86%E4%BA%AB_JavaScript_WEB-ITnose&dict=30&w_qd=IlPT2AEptyoA_yk55g9d63GxJyFTeGcnyFkZeey&sec=21758&di=e4e64d431e4c3c16&bdenc=1&nsrc=IlPT2AEptyoA_yixCFOxXnANedT62v3IEQGG_yVE0DWhmI3tfeSaUbBeZyPuKXPTUS3fdj4KtxoCrizfQjm&clk_info=%7B%22srcid%22%3A%221599%22%2C%22tplname%22%3A%22www_normal%22%2C%22t%22%3A1497450504955%2C%22sig%22%3A%225146%22%2C%22xpath%22%3A%22div-a-h3%22%7D&sfOpen=1

微信是一个很不错的传播平台,最近公司需要做一个新年贺卡,使用html5制作一个很小的动画,然后发送给客户,不需要和后台有任何的联系,一个很简单的功能,需要利用微信的分享功能,毕竟微信分享的带小图片、简介、标题比发送一个链接要比一个光秃秃的链接要高大上的多。好了,废话不多说了,进入正题吧。

刚开始我也到网上去搜了一下,看到好多这个版本的,我也贴一下:

var shareData = {        "appid": appid,     //公众号的appID        "img_url": imgUrl,  //缩略图地址        "img_width": "120", //图片的宽度        "img_height": "120",//图片的高度        "link": lineLink,   //分享的链接        "desc": descContent,//摘要的信息        "title": shareTitle //分享的标题,默认为网页标题        };        function shareFriend() {        WeixinJSBridge.invoke('sendAppMessage',shareData, function(res) {            //定义分享完成后的事            alert(dasd);        })    }    function shareTimeline() {        WeixinJSBridge.invoke('shareTimeline',shareData, function(res) {               //_report('timeline', res.err_msg);        });    }    // 当微信内置浏览器完成内部初始化后会触发WeixinJSBridgeReady事件。    document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {        // 发送给好友        WeixinJSBridge.on('menu:share:appmessage', function(argv){            shareFriend();        });        // 分享到朋友圈        WeixinJSBridge.on('menu:share:timeline', function(argv){            shareTimeline();        });    }, false);

可能这个版本在微信没有发布js-sdk时是有用的,但是现在微信好像把这个方法设置了权限,这个方法已经不可用了,所以我到微信官方去看了一下,微信js-sdk已经支持开发接口支持微信分享了,怎么实现,下面一一道来:

微信官方js-sdk链接地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html 有兴趣可以自己去研究研究,下面只是我自己的一些经验,水平有限,有错误之处欢迎大家指出。

1. 要使用js-sdk,首先你得拥有一个微信认证过的订阅号或者服务号(个人认为如果开发的还是服务号好),然后按照微信js-sdk api的步骤来,先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。js接口安全域名可以设置三个,意思是你的网页要想使用js-sdk,访问就必须在这个域名下(如果域名带有端口号,设置的时候也必须带有端口号,微信上虽然说只支持80端口,但是我用其他端口好像也可以)。

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

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

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

4.通过ready接口处理成功验证。

wx.ready(function () {    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。      var shareData = {        title: title, // 分享标题        desc: desc, // 分享描述        link: link, //网页地址        imgUrl: imgUrl, //小图片的地址        success: function () {            // 用户确认分享后执行的回调函数        },        cancel: function () {            // 用户取消分享后执行的回调函数        }      };      wx.onMenuShareAppMessage(shareData);      wx.onMenuShareTimeline(shareData);  });

5.以上就是微信文档中的处理js-sdk接口的基本步骤,完成了这些,就可以完成一个如下的分享框:

6.上面的这些步骤都是微信文档上有的,copy就行,我个人觉得初次接触,微信js-sdk的config配置相对来说是要复杂一点。就是第三点里面的签名比较难一点,下面我就详细的说一下我是怎么获得配置的参数的(appid,timestamp,noncestr,signature);首先找到js-sdk生成签名的文档,阅读发现signature的生成是需要密钥的,就是我们公众号AppSecret,这个东西是不能被别人知道的,所以我们处理密钥一定要在后台处理,在html处理的话会泄漏你的公众号关注者的信息的。所以我们得在后台写一个接口,用来返回config里的配置信息;后台怎么处理呢?(后台是用java写的)

1>首先随机生成一个字符串(noncestr)和一个随机时间戳(timestamp),这就解决了两个配置项;

noncestr  = Double.toString(Math.random()).substring(2, 15);//随机字符串timeStamp =((int)(new Date().getTime()/1000))+"";//随机时间戳

2>然后就的获得微信的基础支持,访问微信的https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET接口,获得返回来的access_token;

public String getAccess_token(){        System.out.println("重新请求access_token");        String access_token = "";        String str = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&";        str += "appid=" + APPID + "&secret=" + APPSECRET;        try {            URL url = new URL(str);            HttpURLConnection connection = (HttpURLConnection)url.openConnection();            connection.setRequestMethod("GET");            connection.setConnectTimeout(CONNECTTIMEOUT);            connection.setReadTimeout(READTIME);            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));            StringBuffer stringBuffer = new StringBuffer();            String temp = "";            while((temp = bufferedReader.readLine())!= null){                stringBuffer.append(temp);                System.out.println(temp);            }            String result = stringBuffer.toString();            JSONObject root = JSONObject.fromObject(result);            access_token = root.getString("access_token");            bufferedReader.close();                    } catch (MalformedURLException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return access_token;    }

3>获得微信的access_token后,就可以获得jsapi_ticket了,访问微信的https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi接口,获得返回来的jsapi_ticket;

public String getJsapi_ticket(String access_token){        System.out.println("重新请求jsapi_ticket");        String jsapi_ticket = "";        String str = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";        try {            URL url = new URL(str);            HttpURLConnection connection = (HttpURLConnection)url.openConnection();            connection.setRequestMethod("GET");            connection.setConnectTimeout(CONNECTTIMEOUT);            connection.setReadTimeout(READTIME);            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));            StringBuffer stringBuffer = new StringBuffer();            String temp = "";            while((temp = bufferedReader.readLine())!= null){                stringBuffer.append(temp);            }            String result = stringBuffer.toString();            JSONObject root = JSONObject.fromObject(result);            jsapi_ticket = root.getString("ticket");            bufferedReader.close();                    } catch (MalformedURLException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return jsapi_ticket;    }

4>获得jsapi_ticket,noncestr,timestamp还有你的网页地址后就可以生成签名了;

public WeiXinJsServer(String url,HttpServletRequest request) {        this.noncestr  = Double.toString(Math.random()).substring(2, 15);        this.timeStamp =((int)(new Date().getTime()/1000))+"";        String access_token = getAccess_token();        String Jsapi_ticket = getJsapi_ticket(access_token);        String str = "jsapi_ticket=" + Jsapi_ticket + "&noncestr=" + noncestr + "×tamp="+ timeStamp +"&url=" + url;        this.signature = new SHA1().getDigestOfString(str.getBytes());     }

5>最后在奉上sha1算法;签名测试地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

public class SHA1 {     private final int[] abcde = {             0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0         };     private int[] digestInt = new int[5];     private int[] tmpData = new int[80];     private int process_input_bytes(byte[] bytedata) {         System.arraycopy(abcde, 0, digestInt, 0, abcde.length);         byte[] newbyte = byteArrayFormatData(bytedata);         int MCount = newbyte.length / 64;         for (int pos = 0; pos < MCount; pos++) {             for (int j = 0; j < 16; j++) {                 tmpData[j] = byteArrayToInt(newbyte, (pos * 64) + (j * 4));             }             encrypt();         }         return 20;     }     private byte[] byteArrayFormatData(byte[] bytedata) {         int zeros = 0;         int size = 0;         int n = bytedata.length;         int m = n % 64;         if (m < 56) {             zeros = 55 - m;             size = n - m + 64;         } else if (m == 56) {             zeros = 63;             size = n + 8 + 64;         } else {             zeros = 63 - m + 56;             size = (n + 64) - m + 64;         }         byte[] newbyte = new byte[size];         System.arraycopy(bytedata, 0, newbyte, 0, n);         int l = n;         newbyte[l++] = (byte) 0x80;         for (int i = 0; i < zeros; i++) {             newbyte[l++] = (byte) 0x00;         }         long N = (long) n * 8;         byte h8 = (byte) (N & 0xFF);         byte h7 = (byte) ((N >> 8) & 0xFF);         byte h6 = (byte) ((N >> 16) & 0xFF);         byte h5 = (byte) ((N >> 24) & 0xFF);         byte h4 = (byte) ((N >> 32) & 0xFF);         byte h3 = (byte) ((N >> 40) & 0xFF);         byte h2 = (byte) ((N >> 48) & 0xFF);         byte h1 = (byte) (N >> 56);         newbyte[l++] = h1;         newbyte[l++] = h2;         newbyte[l++] = h3;         newbyte[l++] = h4;         newbyte[l++] = h5;         newbyte[l++] = h6;         newbyte[l++] = h7;         newbyte[l++] = h8;         return newbyte;     }     private int f1(int x, int y, int z) {         return (x & y) | (~x & z);     }     private int f2(int x, int y, int z) {         return x ^ y ^ z;     }     private int f3(int x, int y, int z) {         return (x & y) | (x & z) | (y & z);     }     private int f4(int x, int y) {         return (x << y) | x >>> (32 - y);     }     private void encrypt() {         for (int i = 16; i <= 79; i++) {             tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14] ^                     tmpData[i - 16], 1);         }         int[] tmpabcde = new int[5];         for (int i1 = 0; i1 < tmpabcde.length; i1++) {             tmpabcde[i1] = digestInt[i1];         }         for (int j = 0; j <= 19; j++) {             int tmp = f4(tmpabcde[0], 5) +                 f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +                 tmpData[j] + 0x5a827999;             tmpabcde[4] = tmpabcde[3];             tmpabcde[3] = tmpabcde[2];             tmpabcde[2] = f4(tmpabcde[1], 30);             tmpabcde[1] = tmpabcde[0];             tmpabcde[0] = tmp;         }         for (int k = 20; k <= 39; k++) {             int tmp = f4(tmpabcde[0], 5) +                 f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +                 tmpData[k] + 0x6ed9eba1;             tmpabcde[4] = tmpabcde[3];             tmpabcde[3] = tmpabcde[2];             tmpabcde[2] = f4(tmpabcde[1], 30);             tmpabcde[1] = tmpabcde[0];             tmpabcde[0] = tmp;         }         for (int l = 40; l <= 59; l++) {             int tmp = f4(tmpabcde[0], 5) +                 f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +                 tmpData[l] + 0x8f1bbcdc;             tmpabcde[4] = tmpabcde[3];             tmpabcde[3] = tmpabcde[2];             tmpabcde[2] = f4(tmpabcde[1], 30);             tmpabcde[1] = tmpabcde[0];             tmpabcde[0] = tmp;         }         for (int m = 60; m <= 79; m++) {             int tmp = f4(tmpabcde[0], 5) +                 f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +                 tmpData[m] + 0xca62c1d6;             tmpabcde[4] = tmpabcde[3];             tmpabcde[3] = tmpabcde[2];             tmpabcde[2] = f4(tmpabcde[1], 30);             tmpabcde[1] = tmpabcde[0];             tmpabcde[0] = tmp;         }         for (int i2 = 0; i2 < tmpabcde.length; i2++) {             digestInt[i2] = digestInt[i2] + tmpabcde[i2];         }         for (int n = 0; n < tmpData.length; n++) {             tmpData[n] = 0;         }     }     private int byteArrayToInt(byte[] bytedata, int i) {         return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16) |         ((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff);     }     private void intToByteArray(int intValue, byte[] byteData, int i) {         byteData[i] = (byte) (intValue >>> 24);         byteData[i + 1] = (byte) (intValue >>> 16);         byteData[i + 2] = (byte) (intValue >>> 8);         byteData[i + 3] = (byte) intValue;     }     private static String byteToHexString(byte ib) {         char[] Digit = {                 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',                 'D', 'E', 'F'             };         char[] ob = new char[2];         ob[0] = Digit[(ib >>> 4) & 0X0F];         ob[1] = Digit[ib & 0X0F];         String s = new String(ob);         return s;     }     private static String byteArrayToHexString(byte[] bytearray) {         String strDigest = "";         for (int i = 0; i < bytearray.length; i++) {             strDigest += byteToHexString(bytearray[i]);         }         return strDigest;     }     public byte[] getDigestOfBytes(byte[] byteData) {         process_input_bytes(byteData);         byte[] digest = new byte[20];         for (int i = 0; i < digestInt.length; i++) {             intToByteArray(digestInt[i], digest, i * 4);         }         return digest;     }     public String getDigestOfString(byte[] byteData) {         return byteArrayToHexString(getDigestOfBytes(byteData));     }     public static void main(String[] args) {         String data = "123456";         System.out.println(data);         String digest = new SHA1().getDigestOfString(data.getBytes());         System.out.println(digest);    } }

6>最后在页面调用一下就可以了。

$(document).ready(function(e) {        var url = location.href;         $.ajax({            url:"http://test/WeiXinJsSdkConfiger",            data:{                "url":url                }, //以键/值对的形式            async : true,            dataType : "jsonp",            jsonp: "callbackparam",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)            jsonpCallback:"success_jsonpCallback",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名            success : function(data) {                wx.config({                  debug: false,                  appId: data.appid,                  timestamp: data.timeStamp,                  nonceStr: data.noncestr,                  signature: data.signature,                  jsApiList: [                    'onMenuShareTimeline',                    'onMenuShareAppMessage',                  ]                  });            }         });        wx.ready(function(){             var shareData = {            title: '1111111', // 分享标题            desc: '111111', // 分享描述            link: location.hostname+location.pathname,            imgUrl: '11111'          };          wx.onMenuShareAppMessage(shareData);          wx.onMenuShareTimeline(shareData);         });});

获得access_token和jsapi_ticket有必要的可缓存一下,个人建议这样,大概这样可以实现微信分享了,其实这样js-sdk中所有的函数都可以使用了,其实很简单的,

原创粉丝点击