我的公众号原文地址

⚠️ 很要害的前提 ⚠️
❗️集体开发者应用wx-jssdk的权限受限❗️(无转发给好友、分享朋友圈等权限),可先去「设置与开发-接口权限」查看权限详情。
♂️文末是我说的「体面」❗️

公众号设置

服务端代码

(基于Koa2开发,省略服务器搭建代码,仅提供关键步骤代码)
1.编写「服务器配置-服务器地址(URL)」所须要的接口地址
https://yourserver.com/api/ch...
let sha1 = require("sha1");/** * 微信公众号-指定服务器地址-验证接口 * @param {*} ctx */checkToken: async (ctx) => {  const { signature, timestamp, nonce, echostr } = ctx.query;  //ctx.query获取申请中携带的参数  let { token } = wxconfig;  //将Token,timestamp,nonce按字典排序,排序后链接成一个字符串  let str = [token, timestamp, nonce].sort().join("");  //应用sha1模块进行sha1加密  let sha1Str = sha1(str);  //判断加密后的字符串与申请中signature是否相等  if (sha1Str === signature) {    ctx.body = echostr;  } else {    ctx.body = "Token check failed.";  }};

这一步OK之后,在「微信公众号后盾就能胜利开启服务器了」。接下来就是编写H5在微信里调用wx-jssdk相干性能所须要的受权过程。其实次要就是拿到wxconfig所须要的一些必要参数

编写wx.config所需数据的接口
https://yourserver.com/api/wx...需受权网站的url

生成wxconfig数据的大抵流程:获取access_token,通过access_token获取jsapi_ticket;而后拼接access_tokenjsapi_ticketnoncestrtimestamp要受权的页面的url生成签名signature,最终将appIdtimestampnonceStrsignature返回给前端,前端调用wx.config进行注册,胜利后就能够在wx.ready中调用相干js接口了。

wxConfig.js文件代码
!!!这里局部代码借鉴来的,懒得改了大抵流程都是这样!
const sha1 = require("sha1");const request = require("request");const { wxconfig } = require("./wxConfig");// 为了应答缓存压力,不要每次刷新token,访问量高会带来很大问题// 因为获取access_token的接口,一天最多调用2000次,每次有效期是两个小时let CACHE = {  ticket: "",  ticketTimeout: 0, //ticket过期工夫  ticketTime: 0, //获取ticket工夫  accessToken: "",  accessTokenTimeout: 0, //token过期工夫  accessTokenTime: 0, //获取token工夫};class wxModel {  /**   * 刷新access_token   */  static async refreshAccessToken() {    return new Promise((resolve, reject) => {      const tokenUrl = `${wxconfig.getAccessTokenUrl}?grant_type=client_credential&appid=${wxconfig.appId}&secret=${wxconfig.appSecret}`;      request(tokenUrl, (error, response, body) => {        if (typeof body === "string") {          try {            body = JSON.parse(body);          } catch (e) {            body = {              errcode: "-1000",              body,            };          }        }        if (body && (!body.errcode || body.errcode == 0)) {          CACHE.accessToken = body.access_token;          CACHE.accessTokenTimeout = body.expires_in * 500;          CACHE.accessTokenTime = new Date();          resolve(CACHE.accessToken);        } else if (body) {          reject(body.errmsg);        } else {          reject("未知异样");        }      });    });  }  /**   * 刷新ticket   * @param {*} access_token   * @param {*} callback   */  static async refreshJsapiTicket(access_token) {    // Jsapi_ticket    return new Promise((resolve, reject) => {      let ticketUrl = `${wxconfig.getJsapiTicketUrl}?access_token=${access_token}&type=jsapi`;      request(ticketUrl, function (err, response, content) {        content = JSON.parse(content);        if (content && (content.errcode == 0 || !content.errcode)) {          CACHE.ticket = content.ticket;          CACHE.ticketTimeout = content.expires_in * 500;          CACHE.accessTokenTime = new Date();          resolve(CACHE.ticket); // ticket        } else if (content) {          reject(content.errmsg);        } else {          reject("未知异样");        }      });    });  }  /**   * 获取wxconfig   * @param {*} url   * @returns   */  static async geneWxConfig(url) {    // 获取access_token    let access_token = CACHE.accessToken;    let ticket = CACHE.ticket;    if (      !access_token ||      new Date() - CACHE.accessTokenTime > CACHE.accessTokenTimeout    ) {      access_token = await this.refreshAccessToken();      ticket = await this.refreshJsapiTicket(access_token);    }    let nonceStr = this.createNonceStr();    let timestamp = this.createTimestamp();    let signature = this.createSign({      jsapi_ticket: ticket,      nonceStr,      timestamp,      url,    });    return {      appId: wxconfig.appId,      access_token,      ticket,      timestamp,      nonceStr,      signature,    };  }  /**   * 随机字符串   */  static createNonceStr() {    return Math.random().toString(36).substr(2, 15);  }  /**   * 工夫戳   */  static createTimestamp() {    return parseInt(new Date().getTime() / 1000).toString();  }  /**   * 生成签名   * ⚠️ 只对url#后面局部加密   * ⚠️ noncestr全副小写   * @param {*} config   */  static createSign(config) {    let ret = {      jsapi_ticket: config.jsapi_ticket,      nonceStr: config.nonceStr,      timestamp: config.timestamp,      url: config.url,    };    let url = ret.url.split("#")[0];    let string = `jsapi_ticket=${ret.jsapi_ticket}&noncestr=${ret.nonceStr}&timestamp=${ret.timestamp}&url=${url}`;    let shaObjs = sha1(string);    return shaObjs;  }}module.exports = wxModel;
wxConfig.js文件内容
const wxconfig = {  appId: "wx9xxxxxxx",  appSecret: "xxxxxxxxxxxxxxxxxxxxx",  token: "hxxxt", //公众号后盾自行配置的token  getAccessTokenUrl: "https://api.weixin.qq.com/cgi-bin/token",  getJsapiTicketUrl: "https://api.weixin.qq.com/cgi-bin/ticket/getticket",};module.exports = {  wxconfig,};

前端代码

1.引入wx-jssdk
let jssdkUri = `${window.location.protocol}//res.wx.qq.com/open/js/jweixin-1.6.0.js`;loadJs() {  return new Promise((resolve, reject) => {    if (window.wx) {      return resolve(window.wx);    }    let script = document.createElement("script");    script.type = "text/javascript";    script.src = this.jssdkUri;    window.document.getElementsByTagName("head")[0].appendChild(script);    script.onload = () => {      resolve(window.wx);    };    script.onerror = reject;  });}
2.申请 /api/wxconfig 接口,拿到必要数据后调用 wx.config
let url = window.location.href;let data = await this.getWxconfig(url);wx.config({  debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert进去,若要查看传入的参数,能够在pc端关上,参数信息会通过log打出,仅在pc端时才会打印。  appId: data.appId, // 必填,公众号的惟一标识  timestamp: data.timestamp, // 必填,生成签名的工夫戳  nonceStr: data.nonceStr, // 必填,生成签名的随机串  signature: data.signature, // 必填,签名  jsApiList: [    "hideMenuItems",    "updateAppMessageShareData",    "updateTimelineShareData",  ], // 必填,须要应用的JS接口列表});
3.在wx.ready中编写「分享、转发」和其它业务须要的办法
share({ title, desc, link, imgUrl }) {  this.shareData = { title, desc, link, imgUrl };  if (!this.isReady) {    console.error("wx jssdk is not ready.");    return;  }  wx.ready(() => {    wx.updateAppMessageShareData({      title,      desc,      link,      imgUrl, // 分享图标      success: (res) => {},      fail: (err) => this.onError(err),    });    wx.updateTimelineShareData({      title,      link,      imgUrl, // 分享图标      success: (res) => {},      fail: (err) => this.onError(err),    });  });}hideMenu() {  if (!this.isReady) {    console.error("wx jssdk is not ready.");    return;  }  wx.ready(() => {    wx.hideMenuItems({      menuList: [        "menuItem:share:appMessage",        "menuItem:share:timeline",        "menuItem:share:qq",        "menuItem:share:weiboApp",        "menuItem:share:QZone",        "menuItem:copyUrl",      ],    });  });}
如何让H5在微信里活的「体面」!

最初想说一下,作为一个集体开发者无奈调用wx.updateAppMessageShareDatawx.updateTimelineShareData等一些接口,我是怎么利用无限的性能让我的H5网页尽量「体面」的吧!

既然不能分享,那罗唆干掉微信点击右上角性能按钮后弹出来的「转发给敌人」和「分享到朋友圈」,甚至干掉「复制链接」性能菜单。

这样尽量减少转发进来只剩下袒露的难看的url链接的状况产生。

(请看比照图)

至于如何流传这个H5网页?给H5生成一个二维码,贴在一张难看的图片上,转发给敌人吧哈哈哈!

顺便附上一个Amazing的收费在线 二维码生成网站