yanyue404 / blog

Just blog and not just blog.
https://yanyue404.github.io/blog/
Other
88 stars 13 forks source link

H5链接拉起微信小程序 #224

Open yanyue404 opened 2 years ago

yanyue404 commented 2 years ago

怎样在各个环境打开微信小程序

  1. 【微信外部浏览器】打开方案:URL Scheme 链接

在微信小程序后台配置生成,得到 Scheme 链接可以在外部浏览器环境打开小程序。

# 输入:

- 小程序页面路径: pages/home/home
- 启动 query 参数: fromId=72472

# 输出:

weixin://dl/business/?t=ccxxxxxx
  1. 【微信内部浏览器】打开方案: 开放标签 <wx-open-launch-weapp>

说明:

微信开放标签使用步骤与微信 JS-SDK 类似,需要引入 JS 文件等步骤,并通过 config 接口注入权限验证配置并申请所需的开放标签。

参数:

用例示例:

<wx-open-launch-weapp
  id="launch-btn"
  username="gh_xxxxxxxx"
  path="pages/home/index?user=123&action=abc"
>
  <script type="text/wxtag-template">
    <style>.btn { padding: 12px }</style>
    <button class="btn">打开小程序</button>
  </script>
</wx-open-launch-weapp>
<script>
  var btn = document.getElementById('launch-btn');
  btn.addEventListener('launch', function (e) {
    console.log('success');
  });
  btn.addEventListener('error', function (e) {
    console.log('fail', e.detail);
  });
</script>
  1. 【微信小程序 webview】打开方案:wx.miniProgram.switchTabwx.miniProgram.navigateTo
const toMiniProgram = () => {
  const tabBar = [
    "pages/home/home",
    "pages/productList/productList",
    "pages/mine/mine",
  ];
  let url = this.path;
  let [path, query = ""] = url.split("?");
  if (tabBar.includes(path) || url === "") {
    console.log("跳 tab", url || "pages/home/home");
    wx.miniProgram.switchTab({
      url: url ? "/" + url : "/pages/home/home",
    });
  } else {
    console.log("跳 navigateTo", url);
    wx.miniProgram.navigateTo({
      url: "/" + url,
    });
  }
};

打开链接:https://xxx.cn/sms-to-miniprogram/#/?url=weixin%3A%2F%2Fdl%2Fbusiness%2F%3Ft%3DJLL3qb69Bid&path=pages%2Fhome%2Fhome

微信小程序 URL Scheme 生成规则调整

3.9 日微信发布新规则,自 2022 年 4 月 11 日起,URL Scheme 和 URL Link (以下统称为 “链接” )接口能力规则将进行以下调整:

  1. 每个 URL Scheme 或 URL Link 有效期最长 30 天,均不再支持永久有效的链接、不再区分短期有效链接与长期有效链接;
  2. 链接生成后,若在微信外打开,用户可以在浏览器页面点击进入小程序。每个独立的链接被用户访问后,仅此用户可以再次访问并打开对应小程序,其他用户无法再次通过相同链接打开该小程序;
  3. 单个小程序每天生成链接数(URL Scheme 和 URL Link 总数)上限为 50 万条。

对业务的影响:

  1. 每个 URL Scheme 将仅支持一个用户访问——需支持动态生成链接,每个用户生成单独的。
  2. 每个 URL Scheme 有效期最长 30 天,需考虑长期链接到期后替换规则。
  3. 每天生成上限为 50w。

实现思路

  1. 访问小程序的 H5 链接改为:基础链接+小程序路径
  2. 用户访问 H5 页面时,微信环境使用开放标签跳转,非微信环境下,前端根据链接上携带的落地的小程序路径 + 用户 deviceId 向服务端查询 URL Scheme 链接并完成跳转
  3. 服务端根据落地小程序路径 + 用户 deviceId 查询是否存在 scheme,以及 scheme 是否有效
    • a. 若已存在 scheme,且仍在有效期,则直接返回已生成的 scheme 给前端
    • b. 若已存在 scheme,但已失效,或距离失效时间< 10 分钟,则重新生成 scheme 返回给前端,且存储此次生成记录,覆盖之前记录的 scheme
    • c. 若未存在 scheme,则生成 scheme 返回给前端,且存储此次生成记录
  4. 服务端需以落地页 + 用户(deviceId)维度存储 scheme 生成记录
  5. 异常情况
    • a. 若 scheme 生成失败,则服务端需返回给前端默认小程序首页 scheme,生成规则( path——pages/home/home):
    • b. 若前端未获取到必填字段信息,也去服务端取默认 scheme

生成设备 deviceId 的方案

import FingerprintJS from "@fingerprintjs/fingerprintjs";

const createVisitorId = async () => {
  const fp = await FingerprintJS.load({ screen_resolution: true });
  const result = await fp.get();
  const visitorId = result.visitorId;
  return visitorId;
};

改版后的打开链接:https://xxx.cn/sms-to-miniprogram/#/?path=pages%2Fhome%2Fhome

微信小程序支持打开新版微信公众号 webview

if (!this.isWeixin && !this.isMiniProgram) {
  const schema = await this.getSchemaURL(this.path);
  this.schema = schema;
  location.href = schema;
} else {
  // 微信环境下打开微信公众号的新版链接适配,? 后参数需转义
  let params = this.path.match(/https:\/\/mp\.weixin\.qq\.com\/s\?(.*)/);
  if (params && params[1]) {
    this.path =
      "pages/web-page/web-page?url=https://mp.weixin.qq.com/s?" +
      encodeURIComponent(params[1]);
  }
}

参考