SoFunction
Updated on 2024-10-30

WeChat JS-SDK simple application implementation based on nodejs

2015 is the year of the rise of Hybrid App, Web App and Native App each has its own strong points, but also has a fatal shortcomings, people while pursuing native smooth user experience, while at the same time expect the product can be quickly iterative update, Hybrid become an inevitable trend.

Goose Factory took the lead and released the industry's shocking JS-SDK, which is manna for WeChat-based h5 developers. From now on, developers will say goodbye to the use of arrows to indicate that the upper-right corner can be shared, and can use WeChat's native capabilities at any time, and WeChat has turned into a superbrowser.

I. Preparatory work

1. Apply for a test account on the WeChat public platform and set up a good JS interface security domain name (Note: the domain name must be accessible from outside the network)

2. ViewWeChat Developer Documentation

II. Commencement of coding

To use the WeChat sdk you must implement the WeChat signature algorithm yourself.

It takes about 4 steps:

1. Get access_token;

2. Get jsapi_ticket based on access_token

3. according to appId (public unique id), noncestr (random string), timestamp (timestamp), url (the current page full url, excluding #aaa=bbb) by sha1 algorithm signature

4. Return the information to the front end , set.

Since the interfaces for access_token and jsapi_ticket have access restrictions, it is explicitly stated that they need to be cached by a third party. In this case, we'll just cache the jsapi_ticket.

/config/

 = {
  grant_type: 'client_credential',
  appid: 'xxxxxxxxxxxxxxx',
  secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
  noncestr:'Wm3WZYTPz0wzccnW',
  accessTokenUrl:'/cgi-bin/token',
  ticketUrl:'/cgi-bin/ticket/getticket',
  cache_duration:1000*60*60*24 //Cache length is 24 hours
}

The main part is the signature:

var request = require('request'),
  cache = require('memory-cache'),
  sha1 = require('sha1'),
  config = require('../config/');

 = function (url,callback) {
  var noncestr = ,
    timestamp = (()/1000), //accurate to the second
    jsapi_ticket;
  if(('ticket')){
    jsapi_ticket = ('ticket');
    ('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( + '?grant_type=' + config.grant_type + '&appid=' +  + '&secret=' +  ,function(error, response, body){
      if (!error &&  == 200) {
        var tokenMap = (body);
        request( + '?access_token=' + tokenMap.access_token + '&type=jsapi', function(error, resp, json){
          if (!error &&  == 200) {
            var ticketMap = (json);
            ('ticket',,config.cache_duration); // Add to cache
            ('jsapi_ticket=' +  + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url);
            callback({
              noncestr:noncestr,
              timestamp:timestamp,
              url:url,
              jsapi_ticket:,
              signature:sha1('jsapi_ticket=' +  + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url)
            });
          }
        })
      }
    })
  }
}

Since it's just a simple demo, it doesn't use promises, but regular callbacks.

client part

('refresh').onclick = function(){();}

/**
 * The following is mostly taken from the official demos
 /* /* /* The following is mostly extracted from the official demos.
**/
({
  debug: true, // Enable debug mode, the return value of all api calls will be alerted on the client side, if you want to see the incoming parameters, you can open it on the pc side, the parameter information will be typed out through the log, and will only be printed on the pc side.
  appId: appId, // Required, unique identifier for the public number
  timestamp: timestamp, // Mandatory, time stamp for signature generation
  nonceStr: nonceStr, // Mandatory, random string to generate signature
  signature: signature,// Mandatory, signature, see appendix 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'] // Mandatory, list of JS interfaces to be used.
});

(function(){
 // 1 Determine if the current version supports the specified JS interface, supports batch determination.
 ('#checkJsApi').onclick = function () {
  ({
   jsApiList: [
    'getNetworkType',
    'previewImage'
   ],
   success: function (res) {
    alert((res));
   }
  });
 };

  // 2. Sharing interface
 // 2.1 Listening for "share with friends", button clicks, customized share content, and share result interfaces.
 ('#onMenuShareAppMessage').onclick = function () {
  ({
   title: 'Son of the Internet',
   desc: 'It was only in the process of growing up that I slowly realized that all the things around me, all the things people told me, the things that were supposedly the way they were, the things that were destined to be the way they were, they didn't really have to be the way they were, and that things could be changed. More importantly, some things should be changed since they are wrong.',
   link: '/subject/25785114/',
   imgUrl: '/jssdk/images/',
   trigger: function (res) {
    // Don't try to use ajax asynchronous request in the trigger to modify the content of this share, because the client-side share operation is a synchronous operation, and the packet return using ajax will not have been returned yet.
    alert('User clicks send to friend');
   },
   success: function (res) {
    alert('Shared');
   },
   cancel: function (res) {
    alert('Canceled');
   },
   fail: function (res) {
    alert((res));
   }
  });
  alert('Registered for "Send to Friend" status event');
 };

  // 5 Picture Interface
 // 5.1 Taking pictures, local selection
 var images = {
  localId: [],
  serverId: []
 };
 ('#chooseImage').onclick = function () {
  ({
   success: function (res) {
     = ;
    alert('Selected ' +  + ' Pictures ');
   }
  });
 };
  // 5.2 Image Preview
 ('#previewImage').onclick = function () {
  ({
   current: '/view/photo/photo/public/',
   urls: [
    '/view/photo/photo/public/',
    '/view/photo/photo/public/',
    '/view/photo/photo/public/'
   ]
  });
 };

  // 7.2 Getting the current geographic location
 ('#getLocation').onclick = function () {
  ({
   success: function (res) {
    alert((res));
   },
   cancel: function (res) {
    alert('User refused to authorize access to geolocation');
   }
  });
 };

  // 9 WeChat Native Interface
 // 9.1.1 Scanning a QR code and returning the result
 ('#scanQRCode0').onclick = function () {
  ();
 };

});

(function(res){
  (res)
});

At this point, the basic function has been completed. Attach the effect picture

Potholes to step in:

1. Inconsistent signature algorithms: by/debug/cgi-bin/sandbox?t=jsapisign Verify the correctness of the algorithm

It must be completely consistent and extranet accessible. Deploy the code to BAE , or another application engine server.

It needs to be accurate to the second.

Source Code:/liaobin312716/wechat-sdk-demo/

This is the whole content of this article.