微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。
    通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
    本文介绍微信分享的功能:
    一、前台HTML页面使用步骤:
      1.绑定域名:在微信公众号平台的“公众号设置”--->“功能设置”--->“JS接口安全域名”
      2.引入js:<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
      3.通过config接口注入权限配置
         wx.config({
             debug: false, //开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
             appId: data.data.appId, //公众号的唯一标识
             timestamp: data.data.timeStamp, //生成签名的时间戳
             nonceStr: data.data.nonceStr, //生成签名的随机串
             signature: data.data.signature,//签名
             jsApiList: [
                 'onMenuShareAppMessage'
             ] 
         });
        备注:
           config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,
         所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,
         则可以直接调用,不需要放在ready函数中。
             html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,
          而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。
          即前台处理:encodeURIComponent(location.href.split('#')[0])

      4.通过ready接口处理成功验证
        wx.ready(function(){
        
        })
      5.通过error接口处理失败验证
        wx.error(function(res){
      // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
     });
      6.分享接口的使用
        分享内容的接口必须在config中定义
        //获取“分享给朋友”按钮点击状态及自定义分享内容接口、
      wx.onMenuShareAppMessage({
               title: '油钱包—开启任性加油时代', //分享标题
               desc: '你还在实体卡储值加油吗?油钱包开启了“储油”新时代,储油锁价,再也不担心油价上涨了。', //分享描述
               link: 'http://leovir.com/wegas/weixin/weixin/xuanchuan.html', //分享链接
               imgUrl:'http://leovir.com/wegas/weixin/images/banner2.png', //分享图标
               success: function () { 
                   // 用户确认分享后执行的回调函数
               },
               cancel: function () { 
                   // 用户取消分享后执行的回调函数
               }
          });
          
          //分享到朋友圈
          wx.onMenuShareTimeline({
         title: '油钱包—开启任性加油时代', // 分享标题
         link: 'http://leovir.com/wegas/weixin/weixin/xuanchuan.html', // 分享链接
         imgUrl: 'http://leovir.com/wegas/weixin/images/banner2.png', // 分享图标
         success: function () { 
             // 用户确认分享后执行的回调函数
         },
         cancel: function () { 
             // 用户取消分享后执行的回调函数
         }
      });
      
      //“分享到QQ”按钮点击状态及自定义分享内容接口
      wx.onMenuShareQQ({
          title: '油钱包—开启任性加油时代', //分享标题
                desc: '你还在实体卡储值加油吗?油钱包开启了“储油”新时代,储油锁价,再也不担心油价上涨了。', //分享描述
                link: 'http://leovir.com/wegas/weixin/weixin/xuanchuan.html', //分享链接
                imgUrl:'http://leovir.com/wegas/weixin/images/banner2.png', //分享图标
          success: function () { 
             // 用户确认分享后执行的回调函数
          },
          cancel: function () { 
             // 用户取消分享后执行的回调函数
          }
      });
      
      //“分享到腾讯微博”按钮点击状态及自定义分享内容接口
      wx.onMenuShareWeibo({
          title: '油钱包—开启任性加油时代', //分享标题
                desc: '你还在实体卡储值加油吗?油钱包开启了“储油”新时代,储油锁价,再也不担心油价上涨了。', //分享描述
                link: 'http://leovir.com/wegas/weixin/weixin/xuanchuan.html', //分享链接
                imgUrl:'http://leovir.com/wegas/weixin/images/banner2.png', //分享图标
          success: function () { 
             // 用户确认分享后执行的回调函数
          },
          cancel: function () { 
              // 用户取消分享后执行的回调函数
          }
      });
      
       //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口
      wx.onMenuShareQZone({
          ttitle: '油钱包—开启任性加油时代', //分享标题
                desc: '你还在实体卡储值加油吗?油钱包开启了“储油”新时代,储油锁价,再也不担心油价上涨了。', //分享描述
                link: 'http://leovir.com/wegas/weixin/weixin/xuanchuan.html', //分享链接
                imgUrl:'http://leovir.com/wegas/weixin/images/banner2.png', //分享图标
          success: function () { 
             // 用户确认分享后执行的回调函数
          },
          cancel: function () { 
              // 用户取消分享后执行的回调函数
          }
      });
      
  二、后台签名的生成
      jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。
      由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
      access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。
      access_token的存储至少要保留512个字符空间。
      access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
      
    1.参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):../15/54ce45d8d30b6bf6758f68d2e95bc627.html
          公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在微信公众平台官网-开发者中心页中获得(需要已经成为开发者,且帐号没有异常状态)。
       注意调用所有微信接口时均需使用https协议。
       http请求方式: GET
     https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
     (参数说明:secret第三方用户唯一凭证密钥,即appsecret;appid第三方用户唯一凭证;grant_type获取access_token填写client_credential)
     正常情况下,微信会返回下述JSON数据包给公众号:{"access_token":"ACCESS_TOKEN","expires_in":7200}
        2.用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
      返回json: 获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
      {
     "errcode":0,
     "errmsg":"ok",
     "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
     "expires_in":7200
     }
    3.获取签名:
      签名算法
     签名生成规则如下:
      参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。
        a.对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,
        b.使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。
        c.这里需要注意的是所有参数名均为小写字符。
        d.对string1作sha1加密

          MessageDigest md = MessageDigest.getInstance("SHA-1");
          // 对拼接后的字符串进行 sha1 加密
               byte[] digest = md.digest(signature.getBytes());
               signature = byteToStr(digest);
               
               
               //自定义方法:将字节数组转换为十六进制字符串
               private static String byteToStr(byte[] byteArray) {
              String strDigest = "";
              for (int i = 0; i < byteArray.length; i++) {
                  strDigest += byteToHexStr(byteArray[i]);
              }
              return strDigest;
         }
         
         //将字节转换为十六进制字符串
         private static String byteToHexStr(byte mByte) {
             char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                     'B', 'C', 'D', 'E', 'F' };
             char[] tempArr = new char[2];
             tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
             tempArr[1] = Digit[mByte & 0X0F];
             String s = new String(tempArr);
             return s;
         }
   
      注意:前台页面请求后台时对Url进行了编码,后台需要进行解码java.net.URLDecoder.decode(url,"UTF-8");否则签名生成失效


本文转载:CSDN博客