当前位置: 首页 > 新闻动态 > 软件编程

基于nodejs的微信JS-SDK简单应用实现

作者:用户投稿 浏览: 发布日期:2026-01-11
[导读]:这篇文章主要介绍了基于nodejs的微信JS-SDK简单应用实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
目录

    2015 是 Hybrid App 崛起之年 ,Web App 和 Native App 各有其强大之处,也有着致命的缺点,人们一边追求native流畅的用户体验,一边同时期望产品能够快速的迭代更新,Hybrid 成为必然的趋势。

    鹅厂一马当先,发布了业内震惊一时的 JS-SDK , 这对于基于微信的h5开发者来说简直是如降甘露,从此开发者们告别了用箭头来提示右上角可以分享,并且随时可以使用微信的原生能力,微信变成了一个超级浏览器。

    一、准备工作

    1.在微信公众平台申请测试账号,并设置好好 JS 接口安全域名 (注:域名必须可以外网访问)

    2.查看微信开发者文档

    二、开始编码

    使用微信 sdk 必须自己实现微信的签名算法。

    大概需要4个步骤:

    1.获取access_token;

    2.根据access_token 获取jsapi_ticket

    3. 根据 appId(公众号唯一id)、noncestr(随机字符串)、timestamp(时间戳)、url(当前页面完整url,不包括#aaa=bbb) 通过sha1算法签名

    4.将信息返回给前端 , 设置wx.config。

    由于获取access_token 和jsapi_ticket 的接口都有访问限制,所以明确指出需要第三方做缓存处理。此处我们缓存jsapi_ticket 就可以了。

    /config/wechat.cfg.js

    module.exports = {
      grant_type: 'client_credential',
      appid: 'xxxxxxxxxxxxxxx',
      secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
      noncestr:'Wm3WZYTPz0wzccnW',
      accessTokenUrl:'https://api.weixin.qq.com/cgi-bin/token',
      ticketUrl:'https://api.weixin.qq.com/cgi-bin/ticket/getticket',
      cache_duration:1000*60*60*24 //缓存时长为24小时
    }

    最主要部分是签名:

    signature.js

    var request = require('request'),
      cache = require('memory-cache'),
      sha1 = require('sha1'),
      config = require('../config/wechat.cfg');
    
    exports.sign = function (url,callback) {
      var noncestr = config.noncestr,
        timestamp = Math.floor(Date.now()/1000), //精确到秒
        jsapi_ticket;
      if(cache.get('ticket')){
        jsapi_ticket = cache.get('ticket');
        console.log('1' + 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url);
        callback({
          noncestr:noncestr,
          timestamp:timestamp,
          url:url,
          jsapi_ticket:jsapi_ticket,
          signature:sha1('jsapi_ticket=' + jsapi_ticket + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url)
        });
      }else{
        request(config.accessTokenUrl + '?grant_type=' + config.grant_type + '&appid=' + config.appid + '&secret=' + config.secret ,function(error, response, body){
          if (!error && response.statusCode == 200) {
            var tokenMap = JSON.parse(body);
            request(config.ticketUrl + '?access_token=' + tokenMap.access_token + '&type=jsapi', function(error, resp, json){
              if (!error && response.statusCode == 200) {
                var ticketMap = JSON.parse(json);
                cache.put('ticket',ticketMap.ticket,config.cache_duration); //加入缓存
                console.log('jsapi_ticket=' + ticketMap.ticket + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url);
                callback({
                  noncestr:noncestr,
                  timestamp:timestamp,
                  url:url,
                  jsapi_ticket:ticketMap.ticket,
                  signature:sha1('jsapi_ticket=' + ticketMap.ticket + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url)
                });
              }
            })
          }
        })
      }
    }

    由于只是简单的demo , 也就没有采用promise,而是采用的普通的回调。

    客户端部分

    document.getElementById('refresh').onclick = function(){location.reload();}
    
    /**
     * 以下内容多摘自官方demo
     *
    **/
    wx.config({
      debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
      appId: appId, // 必填,公众号的唯一标识
      timestamp: timestamp, // 必填,生成签名的时间戳
      nonceStr: nonceStr, // 必填,生成签名的随机串
      signature: signature,// 必填,签名,见附录1
      jsApiList: ['checkJsApi',
        'onMenuShareTimeline',
        'onMenuShareAppMessage',
        'onMenuShareQQ',
        'onMenuShareWeibo',
        'hideMenuItems',
        'showMenuItems',
        'hideAllNonBaseMenuItem',
        'showAllNonBaseMenuItem',
        'translateVoice',
        'startRecord',
        'stopRecord',
        'onRecordEnd',
        'playVoice',
        'pauseVoice',
        'stopVoice',
        'uploadVoice',
        'downloadVoice',
        'chooseImage',
        'previewImage',
        'uploadImage',
        'downloadImage',
        'getNetworkType',
        'openLocation',
        'getLocation',
        'hideOptionMenu',
        'showOptionMenu',
        'closeWindow',
        'scanQRCode',
        'chooseWXPay',
        'openProductSpecificView',
        'addCard',
        'chooseCard',
        'openCard'] // 必填,需要使用的JS接口列表,
    });
    
    wx.ready(function(){
     // 1 判断当前版本是否支持指定 JS 接口,支持批量判断
     document.querySelector('#checkJsApi').onclick = function () {
      wx.checkJsApi({
       jsApiList: [
        'getNetworkType',
        'previewImage'
       ],
       success: function (res) {
        alert(JSON.stringify(res));
       }
      });
     };
    
      // 2. 分享接口
     // 2.1 监听“分享给朋友”,按钮点击、自定义分享内容及分享结果接口
     document.querySelector('#onMenuShareAppMessage').onclick = function () {
      wx.onMenuShareAppMessage({
       title: '互联网之子',
       desc: '在长大的过程中,我才慢慢发现,我身边的所有事,别人跟我说的所有事,那些所谓本来如此,注定如此的事,它们其实没有非得如此,事情是可以改变的。更重要的是,有些事既然错了,那就该做出改变。',
       link: 'http://movie.douban.com/subject/25785114/',
       imgUrl: 'http://demo.open.weixin.qq.com/jssdk/images/p2166127561.jpg',
       trigger: function (res) {
        // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
        alert('用户点击发送给朋友');
       },
       success: function (res) {
        alert('已分享');
       },
       cancel: function (res) {
        alert('已取消');
       },
       fail: function (res) {
        alert(JSON.stringify(res));
       }
      });
      alert('已注册获取“发送给朋友”状态事件');
     };
    
      // 5 图片接口
     // 5.1 拍照、本地选图
     var images = {
      localId: [],
      serverId: []
     };
     document.querySelector('#chooseImage').onclick = function () {
      wx.chooseImage({
       success: function (res) {
        images.localId = res.localIds;
        alert('已选择 ' + res.localIds.length + ' 张图片');
       }
      });
     };
      // 5.2 图片预览
     document.querySelector('#previewImage').onclick = function () {
      wx.previewImage({
       current: 'http://img5.douban.com/view/photo/photo/public/p1353993776.jpg',
       urls: [
        'http://img3.douban.com/view/photo/photo/public/p2152117150.jpg',
        'http://img5.douban.com/view/photo/photo/public/p1353993776.jpg',
        'http://img3.douban.com/view/photo/photo/public/p2152134700.jpg'
       ]
      });
     };
    
      // 7.2 获取当前地理位置
     document.querySelector('#getLocation').onclick = function () {
      wx.getLocation({
       success: function (res) {
        alert(JSON.stringify(res));
       },
       cancel: function (res) {
        alert('用户拒绝授权获取地理位置');
       }
      });
     };
    
      // 9 微信原生接口
     // 9.1.1 扫描二维码并返回结果
     document.querySelector('#scanQRCode0').onclick = function () {
      wx.scanQRCode();
     };
    
    });
    
    wx.error(function(res){
      JSON.stringify(res)
    });

    至此,基本功能已经完成。附上效果图

    踩的坑:

    1.签名算法不一致: 通过 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 验证算法正确性

    2.url 必须完全一致,并且外网可访问。 将代码部署到 BAE ,或者其他应用引擎服务器上。

    3.timestamp需要精确到秒。

    源码:https://github.com/liaobin312716/wechat-sdk-demo/

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

    免责声明:转载请注明出处:http://www.sczxchw.cn/news/432527.html

    扫一扫高效沟通

    多一份参考总有益处

    免费领取网站策划SEO优化策划方案

    请填写下方表单,我们会尽快与您联系
    感谢您的咨询,我们会尽快给您回复!