接入微信JS-SDK

相关链接:

  1. 微信JS-SDK说明文档

  2. 微信测试号管理

  3. 微信接口调试工具


有一点希望注意:在写代码的时候,要时刻明白写的是前端还是后端。比如某些网页用手机打开,写前端时使用alert调试比较方便,因为浏览器中的console也看不到,特别是在手机端运行时,如果分不清自己写的前后端代码,盯着控制台也是不会有什么输出的。

以下内容均以测试号为例

绑定域名

测试号界面有

  • 测试号信息 appID和appsecret
  • 接口配置信息
  //微信服务器校验 返回echostr才能配置成功
  if (req.query.echostr) {
    console.log('收到微信校验',req.query);
    res.send(req.query.echostr);
    return;
  }
  • JS接口安全域名
  • 模板消息接口
  • 体验接口权限表

绑定域名就是在JS接口安全域名点击修改,修改域名即可

引入js文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js

配置验证信息

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用,通过config接口注入权限验证配置

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名,见附录1
    jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});

这里有几个重点,

  1. 就是签名生成。
  • 确认签名算法正确签名算法校验
  • 确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。
  • 确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。没有参数,基本应该以/结束 例如:https://www.baidu.com/
  • 确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。
  • 确保一定缓存access_token和jsapi_ticket。例如存入本地JSON文件
  • 用来签名的url要动态生成,否则签名会失效,尤其是分享出去的网页会被添加额外的参数

官方demo找到nodejs的案例,里面有sign.js含有签名算法,把它放到自己的项目中,以供使用。案例中用到的第三方库是哪个版本,如果使用新版本有问题,就用案例中的版本。

//获取token的url地址
var token_url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`;
//获取ticket的url地址
var jsapi_ticket = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`;

//注意拿到 token和ticket 一定要保存起来,方便后续使用。微信说2个小时 token失效,可以设置个定时器 比如1.8小时请求一次

// 先执行一次
refesh_token_tickte();
// 创建定时器 每隔1.8小时 刷新一次 token 和ticket
var timer = setInterval(refesh_token_tickte,1000 * 60 * 60 *1.8);

/**
 * 获取token和ticket并存储
 */
function refesh_token_tickte() {
    getaccess_token(token_url, getjsapi_ticket);
}

/**
 * 获取token
 * @param {*url} 获取token的url地址 
 * @param {*callback} callback 
 */
function getaccess_token(url, callback) {
  console.log("正在请求token");
  axios
    .get(token_url)
    .then(function(response) {
      if (!response || !response.data || !response.data.access_token) {
        console.log("未获取到token");
        callback(null, null);
        return;
      }
      callback(null, response.data.access_token);
    })
    .catch(function(err) {
      callback(err, null);
    });
}

/**
 * 回调函数 
 * 根据token获取jsapi_ticket
 * 同时 会生成 签名 并保存到本地
 * @param {*} err 
 * @param {*} token 
 */
function getjsapi_ticket(err, token) {
  if (err || !token) {
    console.log("获取token失败");
    return;
  }
  var jsapi_ticket = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`;
  axios
    .get(jsapi_ticket)
    .then(function(response) {
      if (!response || !response.data || !response.data.ticket) {
        console.log("未获取到jsapi_ticket", response.data.errmsg);
        return;
      }
      //只存储签名
      try {
          var signjson = "./serverjs/sign.json";
        jsonfile.writeFileSync(signjson, {
            access_token:token,
            jsapi_ticket:response.data.ticket
        }, { spaces: 2 });
        console.log("token写入成功");
      } catch (error) {
        console.log("写入文件失败", error.message);
      }

    })
    .catch(function(error) {
      if (error) {
        console.log("获取jsapi_ticket失败", error.message);
      }
    });
}
/**
 * 根据url动态生成签名
 * @param {*configurl} url 
 */
function createCoinfDynamic(url) {
    console.log('要配置的url是',url);
  try {
    //1. 从文件中读取 ticket
    var signinfo = jsonfile.readFileSync(signjson);
    var ticket = signinfo.jsapi_ticket;
    var token = signinfo.access_token;
    //2. 生成签名
    //sign 是引入的sign.js中的函数
    var signature = sign(ticket, url);
    //3. 补充参数 并返回
    signature.appId = appid;
    signature.jsApiList = [
      "chooseImage",
      "uploadImage",
      "getNetworkType",
      "onMenuShareTimeline",
      "onMenuShareAppMessage",
      "hideMenuItems",
      "checkJsApi"
    ];
    signature.token = token;
    return signature;
  } catch (err) {
    console.log("动态生成签名出错",err.message);
    return null;
  }
}

我的url也不是动态生成的,我是收到客户端请求时,生成一个网页,在网页中向服务器发起请求,拿到配置信息,然后去注册。看起来很麻烦,但是工作正常。

router.get('/wechatconfig',function (req,res) {
// 获取微信注册配置信息
  var requesturl = req.url;
  var configurl = requesturl.split("xxconfigurl=")[1].split('#')[0];
  var config = get_config(configurl);
  res.send(config);
});

我本来想的是,收到请求时,直接生成配置信息,然后传递给网页,到时候网页不用向服务端请求,直接就拿到数据了。我用的是ejs模板,的确可以把数据传递过去,但是拿到的数据会有转码,我已经<%- %>但似乎还是不行。所以最后还是用的之前的方法。
因为刚接触这些,应该是用后台数据渲染网页时,掌握的不好。不知道用vue可不可以完成服务器把数据带到网页中。

  1. 接口列表

    像朋友圈是 onMenuShareTimeline 而不是 menuItem:share:appMessage,千万不要写错了,
    写错了就不能响应事件。

  2. 微信的事件最好放在ready里面

wx.ready(function(){
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

//分享到朋友圈的事件
wx.onMenuShareTimeline({
    title: '', // 分享标题
    link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
    imgUrl: '', // 分享图标
    success: function () { 
        // 用户确认分享后执行的回调函数
    },
    cancel: function () { 
        // 用户取消分享后执行的回调函数
    }
});

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

推荐阅读更多精彩内容

  • 【前言】 某天,接到这么一个需求:自定义微信网页分享出来的标题,描述和图标。以前没玩过这个,感觉应该很简单,动手了...
    果汁凉茶丶阅读 6,403评论 0 10
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,661评论 0 15
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 先来看看微信分享效果: 在没有集成微信分享js-sdk前是这样的:没有摘要,缩略图任意抓取正文图片 在集成微信分享...
    思梦PHP阅读 7,394评论 6 4
  • 可能这个十八九岁的年纪谈恋爱真的太不适合。 早知道现在。我们就不要相遇好了,
    蜷愈阅读 122评论 0 0