Express + TypeScript开发微信应用

转载 # Express + TypeScript开发微信应用

在进行微信开发之前,首先需要注册一个微信公众号或者是订阅号,这个是最基本的操作,没有这一步,后面的的步伐很难走。
注册完微信之后,获取appId和appSecret,有了这两个就可以了

第一步、创建项目

$ mkdir ts_node_wx
$ cd ts_node_wx && npm init 

第二步、安装依赖库

安装需要的packages(express, ejs, request以及sha1)

npm install --save express ejs request sha1

安装TypeScript以及之前安装的packages的类型定义。

npm install --save-dev typescript @types/node @types/express @types/request @types/sha1

由于暂时DefinitelyTyped中并没有JSSDK相关的类型定义文件(.d.ts),请将types文件夹(包含类型定义文件wechat.d.ts)复制到根目录(ts_node_wx)中以便TypeScript获取JSSDK的类型定义。

第三步、配置TypeScript

在ts_node_wx根目录下添加TypeScript配置文件tsconfig.json

{
    "compilerOptions": {
        "target": "es6",
        /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
        "module": "commonjs",
        /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
        "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    }
}

可以根据项目的需求自行添加其他编译选项,比如strict。

第四步、核心逻辑讲解

1、获取token

private getWXToken(): Promise<WXToken> {
  return new Promise((resolve, reject) => {
    request.get(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${config.appId}&secret=${config.appSecret}`, (err, res, body) => {
      if (err) {
        return reject(err);
      }

      const token = JSON.parse(body).access_token || '';
      return resolve(new WXToken(token));
    });
  });
}

2、获取ticket

private getWXTicket(token: string): Promise<WXTicket> {
  return new Promise((resolve, reject) => {
    request.get(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`, (err, res, body) => {
      if (err) {
        return reject(err);
      }

      const ticket = JSON.parse(body).ticket || '';
      return resolve(new WXTicket(ticket));
    })
  });
}

3、签名并将数据传递到前端

const url = req.protocol + '://' + req.get('host') + req.originalUrl;

const tokenRes = await this.getWXToken();
const token = tokenRes.token || '';
const ticketRes = await this.getWXTicket(token);
const ticket = ticketRes.ticket || '';
const timestamp = `${parseInt(new Date().getTime() / 1000 + '', 10)}`;

const params = 'jsapi_ticket=' + ticket + '&noncestr=' + config.nonceStr + '&timestamp=' + timestamp + '&url=' + url;
const signature = sha1(params).toString();

let options: Object = {
  title: 'Home | TS Blog',
  message: 'Welcome to the TS Blog',
  appId: config.appId,
  timestamp,
  nonceStr: config.nonceStr,
  signature,
};

this.render(req, res, "index", options);

4、前端代码调用

<html>
  <head>
    <title><%= title %></title>
  </head>
  <body>
    <h1><%= message %></h1>
  </body>
  <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
  <script type="text/javascript">
      wx.config({
          debug: false,
          appId: '<%= appId %>',
          timestamp: '<%= timestamp %>',
          nonceStr: '<%= nonceStr %>',
          signature: '<%= signature %>',
          jsApiList: [
              'checkJsApi',
              'onMenuShareTimeline',
              'onMenuShareAppMessage',
              'onMenuShareQQ',
              'onMenuShareWeibo',
              'onMenuShareQZone',
              'hideMenuItems',
              'showMenuItems',
              'hideAllNonBaseMenuItem',
              'showAllNonBaseMenuItem',
              'translateVoice',
              'startRecord',
              'stopRecord',
              'onVoiceRecordEnd',
              'playVoice',
              'onVoicePlayEnd',
              'pauseVoice',
              'stopVoice',
              'uploadVoice',
              'downloadVoice',
              'chooseImage',
              'previewImage',
              'uploadImage',
              'downloadImage',
              'getNetworkType',
              'openLocation',
              'getLocation',
              'hideOptionMenu',
              'showOptionMenu',
              'closeWindow',
              'scanQRCode',
              'chooseWXPay',
              'openProductSpecificView',
              'addCard',
              'chooseCard',
              'openCard'
          ]
      });
  </script>
  <script type="text/javascript" src="/js/main.js"></script>
</html>

/js/main.js中的内容如下

wx.ready(() => {
  // open specifc location on map
  wx.openLocation({
    latitude: 0,
    longitude: 0,
    name: '千灯裕花园二期',
    address: '江苏省苏州市昆山市千灯镇千灯裕花园二期',
    scale: 1,
    infoUrl: ''
  });
})

第四步、编译并运行项目

$ npm run grunt
$ npm run start 或者 npx pm2 start ecosystem.config.js

走到第四步的时候,有些人看了这篇博文可能会晕,觉得为什么到这一步就完事了。这里我说明下,这里我主要是说如何用TypeScript写一个微信端的应用,怎么去调用微信相关SDK的逻辑,如果需要一个完整的应用的话可能需要花费更多的时间,有需要的同学可以下面留言,我根据需要的人数来做在此分享吧。

当然这个应用也是可以使用的,后面更重要的一步是在项目运行起来后,我们通过nginx做代理转发,将应用绑定到一个域名上面,这个通过域名访问就能够访问到我们的项目,然后项目就能正常的运行起来了。我这边贴一下我这边的整体的代码,地址如下
https://github.com/durban89/ts_node_wx

可以把代码下载后,修改下config文件里面的appId和appSecret之后再部署编译运行。

运行后效果如下

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容