微信开发——开放标签

微信开发——开放标签

前期准备

①微信开放标签可以让第三方页面直接唤起App,避免了通过右上角浏览器中打开再唤起App的麻烦操作。一切按照官方文档说明开发。
②安装微信开发者工具
③一个官方认证的公众服务号,且对应App绑定了该微信服务号,支持跳转。不可使用微信公众平台的测试公众号,否则无法展示开放标签!但是SDK中提供的接口可以在测试号上进行调试。
在这里插入图片描述
④如果使用微信公众平台测试号,需要配置JS接口安全域名网页授权获取用户基本信息,填写正确的域名和端口号。
在这里插入图片描述
在这里插入图片描述
⑤本文使用测试号来演示开放标签<wx-open-launch-app>的使用。前端页面使用VSCode的Live Server本地开启服务器,端口号是5500。后端使用Node的express本地开启服务器,端口号是3000再次注意! 测试号无法展示出开放标签。

前端

注入微信JS-SDK
①请求的微信JS-SDK跨域,所以使用JSONP方法获取SDK脚本,可以使用fetchJsonp第三方库。
②获取页面url、随机字符串nonceStr、时间戳timestamp,发送给后端获取签名signature
③签名的自验可以通过该链接

// JSONP
function jsonp(url) {
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.setAttribute("src", url);
    document.getElementsByTagName("head")[0].appendChild(script);
    script.onload = resolve();
  });
}
// 微信JS-SDK
const wxsdkURL = "//res.wx.qq.com/open/js/jweixin-1.6.0.js";
// 获取签名
const getSignature = (str, time) => {
  const url = encodeURIComponent(location.href.split("#")[0]);
  return ajax.get(
    `${location.protocol}//${location.hostname}:3000/sdk?noncestr=${str}&timestamp=${time}&url=${url}`
  );
};

初始化微信
①将上一步获取的nonceStrtimestampsignature传给window.wx.config(),并设置需要调用的API。

// 初始化微信
const initWeChat = (nonceStr, timestamp, signature) => {
  return new Promise((resolve, reject) => {
    window.wx.config({
      debug: false,
      appId: appId,
      timestamp,
      nonceStr,
      signature,
      jsApiList: [
        "updateAppMessageShareData",
        "updateTimelineShareData",
        "onMenuShareWeibo",
        "chooseImage",
        "uploadImage",
        "downloadImage",
        "previewImage",
        "openLocation",
        "getLocation",
        "closeWindow",
        "scanQRCode",
      ],
      openTagList: ["wx-open-launch-app"],
    });
    window.wx.ready(() => resolve(window.wx));
    window.wx.error(reject);
  });
};
// 整体流程
export const initWxSDK = () => {
  return jsonp(wxsdkURL).then(() => {
    const nonceStr = randomString();
    const timestamp = Math.floor(Date.now() / 1000);
    return getSignature(nonceStr, timestamp).then((signature) =>
      initWeChat(nonceStr, timestamp, signature)
    );
  });
};

使用开放标签和SDK
①开放标签和微信的SDK必须在微信初始化成功后调用,且必须在微信平台。

const scan = document.getElementById("scan");
// 微信扫一扫事件
const handlescan = () => {
  wx.scanQRCode({
    needResult: 0,
    scanType: ["qrCode", "barCode"],
    success: function (res) {
      console.log(res.resultStr);
    },
  });
};
// 调用微信SDK设置右上角分享,开启扫一扫
initWxSDK().then((wx) => {
  const params = {
    title: "测试分享",
    desc: "这里是描述",
    link: shareURL,
    imgUrl: "",
  };
  wx.updateAppMessageShareData(params);
  wx.updateTimelineShareData(params);
  wx.onMenuShareWeibo(params);
  showOpenTag();
  scan.addEventListener("click", handlescan);
});

开放标签样式
①开放标签的样式比较独特,<script>标签内外样式隔离,最好对开放标签外包一层<div>。

/* 开放标签 */
.wxOpenTag {
  position: fixed;
  z-index: 99999;
  bottom: 90px;
  left: 0;
  right: 0;
  margin: 0 auto;
  display: flex;
  justify-content: center;
}
const showOpenTag = () => {
  const openTag = document.createElement("div");
  // 开放标签容器样式
  openTag.className = "wxOpenTag";
  document.getElementsByTagName("body")[0].appendChild(openTag);
  // 开放标签样式
  const style = {
    width: `${transformPx(160)}px`,
    height: `${transformPx(40)}px`,
    fontSize: `${transformPx(14)}px`,
    color: "#fff",
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#37f",
    borderRadius: `${transformPx(8)}px`,
  };
  openTag.innerHTML = `
  <wx-open-launch-app appid=${appId} id="openTag" extinfo=${"someInfo"}>
    <script type="text/wxtag-template"></script>
  </wx-open-launch-app>
  `;
  const ref = document.getElementById("openTag");
  const btn = document.createElement("div");
  addStyle(btn, style);
  btn.innerHTML = "App内打开";
  ref.children[0].appendChild(btn);
  // 开放标签绑定事件
  const launch = (e) => console.log("success");
  const error = (e) => console.log(e.detail);
  ref.addEventListener("launch", launch);
  ref.addEventListener("error", error);
};

后端

获取公众号的access_token

// 获取AccessToken
const getAccessToken = () => {
  return new Promise((resolve, reject) => {
    const URL = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`;
    https
      .get(URL, (res) => {
        let rawData = "";
        res.on("data", (data) => (rawData += data));
        res.on("end", () => resolve(JSON.parse(rawData)));
      })
      .on("error", (e) => console.log(e.message));
  });
};

通过AccessToken获取jsapi_ticket

// 通过AccessToken获取jsapi_ticket
const getJsapiTicket = (access_token) => {
  return new Promise((resolve, reject) => {
    const URL = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`;
    https
      .get(URL, (res) => {
        let rawData = "";
        res.on("data", (data) => (rawData += data));
        res.on("end", () => resolve(JSON.parse(rawData)));
      })
      .on("error", (e) => console.log(e.message));
  });
};

整体流程
①最好将access_tokenjsapi_ticket进行全局缓存,并且定时(2小时)刷新。

// 整体流程
const wxsdk = async () => {
  if (!cache.access_token) {
    const token = await getAccessToken();
    // 请求报错
    if (!token.access_token) {
      return res.send({ code: token.errcode, message: token.errmsg });
    }
    cache.access_token = token.access_token;
    console.log("已缓存access_token: ", cache.access_token);
  }
  if (!cache.jsapi_ticket) {
    const jsapi_ticket = await getJsapiTicket(cache.access_token);
    // 请求报错
    if (jsapi_ticket.errcode) {
      return res.send({
        code: jsapi_ticket.errcode,
        message: jsapi_ticket.errmsg,
      });
    }
    cache.jsapi_ticket = jsapi_ticket.ticket;
    console.log("已缓存jsapi_ticket: ", cache.jsapi_ticket);
  }
  const { noncestr, timestamp, url } = req.query;
  const string = `jsapi_ticket=${
    cache.jsapi_ticket
  }&noncestr=${noncestr}&timestamp=${timestamp}&url=${decodeURIComponent(
    url
  )}`;
  const signature = createHash("sha1").update(string).digest("hex");
  return res.send({
    code: 0,
    message: "success",
    data: signature,
  });
};
wxsdk();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我才是真的李成贤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值