现在的网页大都需要适应手机端和各种屏幕兼容,而且还要在APP的浏览器上运行流畅,就必如现在我们经常使用的微信浏览器,UC,QQ等等,但大部分都是在微信使用的常见,因为要用的微信的一些功能,就必如说微信的分享,支付等等。
这次就我在做的项目使用分享的功能为例简单的说一下怎么在前端去实现。
要做到前端微信分享总共分为 3 个步骤:
1.通过自己的 appidsecret 来获取 access_token 值,用GET请求方式。
访问接口:https://api.weixin.qq.com/cgi-bin/token


$.ajax({
    type: "GET",
    url: 'https://api.weixin.qq.com/cgi-bin/token',
    data: {
        grant_type: 'client_credential', // 默认是固定
        appid: '你的appid',
        secret: '你的secret'
    },
    async: false,
    success: function (ret) {
        setCookie('access_token', ret.access_token, 2)
    }
})

通过拿到的 access_token 值来保存到 cookie 中,因为在微信中经常不能经常调用获取,一般存在的时间是7 200s 也就是两个小时。所以我们在做的时候把第一步的 access_token 值保存起来方便后续的操作。
2.通过在第一步拿到的 access_token 值来获取 jsapi_ticket,也是用的GET请求方式,这里微信提示 jsapi_ticket 的有效期也是 7200s 必要的缓存到全局(这一步我没有做缓存而是直接操作,但是得到的效果也是正常的,如果需要你们可以做个缓存处理)。
访问的地址是:https://api.weixin.qq.com/cgi-bin/ticket/getticket


$.cajax({
    type: "GET",
    url: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket',
    data: {
        type: 'jsapi', // 微信默认参数固定写法
        access_token: $.getCookie('access_token') // 获取第一步中存的cookie值
    },
    success: function (ret) {
        if (ret.errcode == 0) {
            var ticket = ret.ticket;  
            getWxConfig(ticket);
        }
    }
})

3.拿到 ticket 之后配置签名。
签名生成规则如下:参与签名的字段包括 noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分)。
对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。
这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
说这些之前先分享两个函数,
第一个是生成随机字符串 noncestr ,通过时间来截图字符。


// 生成随机串
function getNoncestr() {
    var timestamp = new Date().getTime();
    var Num = "";
    for (var i = 0; i < 6; i++) {
        Num += Math.floor(Math.random() * 10);
    }
    timestamp = timestamp + Num;
    return timestamp;
}
第二个是保存 2 小时的cookie值和读取cookie值

// 保存2小时cookie
function setCookie(name, value, hours) {
    if (hours) {
        var date = new Date();
        date.setTime(date.getTime() + (hours * 60 * 60 * 1000));
        var expires = "; expires=" + date.toGMTString();
    }else {
        var expires = "";
    }
    document.cookie = name + "=" + value + expires + "; path=/";
}
// 读取cookie
function getCookie(name) {
    var obj = {};
    var arr = this.getCookie(name).split('&');
    for (var i = 0, len = arr.length; i < len; i++) {
         var tmpArr = arr[i].split('=');
         obj[decodeURIComponent(tmpArr[0])] = decodeURIComponent(tmpArr[1]);
     }
     return obj;
}

回到第三步,在配置签名的时候一定要注意一下几点:
wx.config 下面的键值 nonceStr 是大写的,timestamp 是小写。且在签名里面的所有键值对都是小写。
拼接的url 地址也是要动态地址,也就是要配置当前网页的的地址 window.location.href
签名一定要进行 sha1 加密处理再传给 wx.config 下的键值signature 中。
具体代码如下:


function getWxConfig(ticket){
   var timestamp = new Date().getTime();
   timestamp = parseInt(timestamp / 1000);

   var noncestr = getNoncestr();
   var url = window.location.href;

   var string1 = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
   wx.config({
       debug: false,
       appId: 'appid',
       timestamp: timestamp,
       nonceStr: noncestr,
       signature: hex_sha1(string1),
       jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'onMenuShareQQ']
   });

   wx.ready(function () {
       // 分享给朋友
       wx.onMenuShareAppMessage({
           title: $("#title").val(), // 分享标题
           desc:  $('#introduce').val(), // 分享描述
           link: $("#jssdkurl").val(), // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
           imgUrl: $("#imgSrc").val(), // 分享图标
           type: 'link', // 分享类型,music、video或link,不填默认为link
           dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
           success: function () {
               // 用户确认分享后执行的回调函数
               mui.toast('分享给朋友成功', { duration: '3000', type: 'div' });
           },
           cancel: function () {
               // 用户取消分享后执行的回调函数
               mui.toast('分享给朋友失败', { duration: '3000', type: 'div' });
           }
       });
       // 分享到朋友圈
       wx.onMenuShareTimeline({
           title: $("#title").val(), // 分享标题
           link: $("#jssdkurl").val(), // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
           imgUrl: $("#imgSrc").val(), // 分享图标
           success: function () {
               // 用户确认分享后执行的回调函数
               mui.toast('分享给朋友圈成功', { duration: '3000', type: 'div' });
           },
           cancel: function () {
               // 用户取消分享后执行的回调函数
               mui.toast('分享给朋友圈失败', { duration: '3000', type: 'div' });
           }
       });
       // 分享到QQ
       wx.onMenuShareQQ({
           title: $("#title").val(), // 分享标题
           desc: $('#introduce').val(), // 分享描述
           link: $("#jssdkurl").val(), // 分享链接
           imgUrl: $("#imgSrc").val(), // 分享图标
           success: function () {
               // 用户确认分享后执行的回调函数
               mui.toast('分享给QQ成功', { duration: '3000', type: 'div' });
           },
           cancel: function () {
               // 用户取消分享后执行的回调函数
               mui.toast('分享给QQ失败', { duration: '3000', type: 'div' });
           }
       });
   });
   wx.error(function (res) {
       mui.toast('微信验证失败', { duration: '3000', type: 'div' });
   });
}

到此微信分享也就差不多搞成了