H5 web page jump applet

Small programs are becoming more and more common now, and there are more and more scenes of jumping from H5 web pages (to be opened under WeChat browser) to corresponding small programs. So far, WeChat has provided corresponding WeChat open tags to allow web developers to use WeChat or the system's capabilities safely and conveniently, providing WeChat users with a better web experience.

It should be noted that there are minimum WeChat version and minimum system version requirements for WeChat Open Label .

  • WeChat version requirements: 7.0.12 and above
  • System version requirements: iOS 10.3 and above, Android 5.0 and above

For scenarios that meet the minimum version requirements of WeChat or the system but still cannot use WeChat open tags , an event will be triggered to notify the developer wx.configafter the permission verification in the steps below is successful. WeixinOpenTagsErrorOnly WeChat development tags cannot be used, and other functions of JS-SDK will not be affected. The following methods can be used to monitor and perform fallback compatibility:

document.addEventListener('WeixinOpenTagsError', function (e) {
  console.error(e.detail.errMsg); // 无法使用开放标签的错误原因,需回退兼容。仅无法使用开放标签,JS-SDK其他功能不受影响
});

According to the currently known error scenarios, the fallback compatibility suggestions are as follows:

  1. The underlying WebKit interface of iOS15 has changed, WeChat versions below 8.0.8 (excluding 8.0.8) cannot use open tags, and users can be guided to upgrade to the latest version of WeChat;
  2. Open tags rely on the Web Components solution, and a very small number of Android systems may not support it because the version is too low, and users can be guided to upgrade the system firmware.

The H5 web page jump applet has the following steps:

1. Bind the "JS interface security domain name" to the WeChat official account ( authenticated service account )

If it is a web page with an official account identity, it needs to be bound with a secure domain name. Log in to the WeChat public platform and enter the "Function Settings" of the "Official Account Settings" to fill in the "JS interface security domain name".

2. Import JS files

Introduce the following JS file on the page that needs to call the JS interface: http://res.wx.qq.com/open/js/jweixin-1.6.0.js (support https)

If you need to further improve service stability, when the above resources are inaccessible, you can change to visit: http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (support https)

Note: js files must use version 1.6.0 or higher

3. Inject authority verification configuration through the config interface and apply for the required open label

In the same way as using the JS-SDK configuration method, all pages that need to use open tags must first inject configuration information and apply for the openTagListrequired open tags through the fields, otherwise they will not be available (the same url only needs to be called once). The application of open tags and the application of JS interface are independent of each other, so they can be applied at the same time.

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

4. Handle successful verification through the ready interface

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

5. Handle failed verification through the error interface

wx.error(function (res) {
  // config信息验证失败会执行 error 函数,如签名过期导致验证失败,具体错误信息可以打开 config 的debug模式查看,也可以在返回的 res 参数中查看,对于 SPA 可以在这里更新签名
});

Instructions for use

The tags used allow slots to be provided, and since the styles of the templates in the slots are isolated from the page, care needs to be taken to define the styles of the templates in the slots. Both slot templates and styles need to be <script type="text/wxtag-template"></script>或<template></template>packaged . slotIn addition, for named slots , the slot name needs to be declared through attributes. The default slot in the label slot below is the default slot, and the slot name can not be declared.

For label events, event.detaildetailed information can be obtained through . Unless otherwise specified, the return values ​​in the label event description below refer to event.detailthe content in .

In addition, the following points need to be noted:

  1. Styles related to layout and positioning in the page, such as position: fixed; top -100;etc., try not to write in the node of the slot template, please declare it on the label or its parent node;
  2. For pages with CSP requirements, you need to add a whitelist frame-src https://*.qq.com webcompt:to use open tags on the page normally.

open object

  1. The certified service account , the service account is bound to the webpage under the "JS interface security domain name", and this label can be used to jump to any legal and compliant applet.
  2. The certified non-personal Mini Program uses the static website developed by Mini Program Cloud to host webpages under the bound domain name. This tag can be used to jump to any legal and compliant Mini Program.

the code

Reference: Static website H5 jump applet | WeChat open document

Directory | WeChat Open Documentation

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>H5跳转小程序</title>
  <!-- weui 样式 -->
  <link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.4.1/weui.min.css">
  <!-- 页面样式 start -->
  <style>
    /* --------START reset.css------- */
    * {
      margin: 0;
      padding: 0;
    }

    html,
    body {
      background-color: #fff;
    }

    a {
      text-decoration: none;
    }

    a,
    button,
    input,
    span,
    div {
      -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    }

    li {
      list-style-type: none;
    }
    /* --------END reset.css------- */

    .hidden {
      display: none;
    }

    .full {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
    }

    .public-web-container,
    .wechat-web-container,
    .wechat-web-container wx-open-launch-weapp,
    .desktop-web-container {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .public-web-container p,
    .wechat-web-container p,
    .desktop-web-container p {
      position: absolute;
      top: 40%;
    }

    .public-web-container a {
      position: absolute;
      bottom: 40%;
    }

    .wechat-web-container wx-open-launch-weapp {
      position: absolute;
      bottom: 40%;
      left: 0;
      right: 0;
    }

    .wechat-web-container .open-btn {
      display: block;
      margin: 0 auto;
      padding: 8px 24px;
      width: 200px;
      height: 45px;
      border: none;
      border-radius: 4px;
      background-color: #07c160;
      color: #fff;
      font-size: 18px;
      text-align: center;
    }
  </style>
  <!-- 页面样式 end -->
</head>

<body>
  <!-- 页面容器 start -->
  <div id="h5OpenMiniprogram">
    <!-- <template> -->
    <!-- 页面内容 start -->
    <div class="page full">
      <!-- 移动端微信外部浏览器 -->
      <div id="public-web-container" class="hidden">
        <p>正在打开“小程序名字”</p>
        <a href="javascript:" id="public-web-jump-button" class="weui-btn weui-btn_primary weui-btn_loading"
          onclick="openWeapp()">
          <span id="public-web-jump-button-loading" class="weui-primary-loading weui-primary-loading_transparent">
            <i class="weui-primary-loading__dot"></i>
          </span>
          打开小程序
        </a>
      </div>

      <!-- 微信内部浏览器 -->
      <div id="wechat-web-container" class="hidden">
        <p>点击以下按钮打开“小程序名字”</p>
        <!-- username:必填,所需跳转的小程序原始id,即小程序对应的以gh_开头的id;path:非必填,所需跳转的小程序内页面路径及参数-->
        <wx-open-launch-weapp id="launch-btn" username="gh_XXX" path="/pages/XXX">
          <!-- 第一种 -->
          <template>
            <style>
              .open-btn {
                display: block;
                margin: 0 auto;
                padding: 8px 24px;
                width: 200px;
                height: 45px;
                border: none;
                border-radius: 4px;
                background-color: #07c160;
                color: #fff;
                font-size: 18px;
                text-align: center;
              }
            </style>
            <button class="open-btn">打开小程序</button>
          </template>
          <!-- 第二种 -->
          <!-- <script type="text/wxtag-template">
            <style>
              .open-btn {
                display: block;
                margin: 0 auto;
                padding: 8px 24px;
                width: 200px;
                height: 45px;
                border: none;
                border-radius: 4px;
                background-color: #07c160;
                color: #fff;
                font-size: 18px;
                text-align: center;
              }
            </style>
            <button class="open-btn">打开小程序</button>
          </script> -->
        </wx-open-launch-weapp>
      </div>

      <!-- 桌面端 -->
      <div id="desktop-web-container" class="hidden">
        <p>请在手机打开网页链接</p>
      </div>
    </div>
    <!-- 页面内容 end -->
    <!-- </template> -->
  </div>
  <!-- 页面容器 end -->

  <!-- 引入jQuery -->
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
  <!-- 调试用的移动端 console -->
  <script src="https://cdn.jsdelivr.net/npm/eruda"></script>
  <script>
    eruda.init();
  </script>
  <!-- 公众号 JSSDK -->
  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
  <!-- 云开发 Web SDK -->
  <script src="https://res.wx.qq.com/open/js/cloudbase/1.1.0/cloud.js"></script>

  <script>
    function docReady(fn) {
      document.addEventListener('WeixinOpenTagsError', function (e) {
        console.error(e.detail.errMsg); // 无法使用开放标签的错误原因,需回退兼容。仅无法使用开放标签,JS-SDK其他功能不受影响
      });
      if (document.readyState === "complete" || document.readyState === "interactive") {
        fn();
      } else {
        document.addEventListener("DOMContentLoaded", fn);
      }
    }

    docReady(async function () {
      var ua = navigator.userAgent.toLowerCase();
      var isWXWork = ua.match(/wxwork/i) == "wxwork";
      var isWeixin = !isWXWork && ua.match(/micromessenger/i) == "micromessenger";
      console.log("isWeixin", isWeixin, isWXWork);
      var isMobile = false;
      var isDesktop = false;
      if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i)) {
        isMobile = true;
      } else {
        isDesktop = true;
      }

      if (isWeixin) {
        var containerEl = document.getElementById("wechat-web-container");
        containerEl.classList.remove("hidden");
        containerEl.classList.add("full", "wechat-web-container");

        // 获取签名,timestamp、nonceStr、signature
        $.ajax({
          url: "请求地址",
          dataType: "json",
          success: function (res) {
            console.log("WeChatConfig", res);
            if (res.id === 1) {
              var data = res.items; // 根据实际情况返还的数据进行赋值
              wx.config({
                // debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
                appId: data.appId, // 必填,公众号的唯一标识
                timestamp: data.timestamp, // 必填,生成签名的时间戳
                nonceStr: data.nonceStr, // 必填,生成签名的随机串
                signature: data.signature, // 必填,签名
                jsApiList: ["chooseImage"], // 必填,需要使用的JS接口列表(此处随意一个接口即可)
                openTagList: ["wx-open-launch-weapp"], // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
              });

              /**
               * config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后。
               * config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。
               * 对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中
               * */
              wx.ready(function (res2) {
                console.log("ready", res2);
                var launchBtn = document.getElementById("launch-btn");
                launchBtn.addEventListener("ready", function (e) {
                  console.log("开放标签 ready");
                });
                launchBtn.addEventListener("launch", function (e) {
                  console.log("开放标签 success");
                });
                launchBtn.addEventListener("error", function (e) {
                  console.log("开放标签 fail", e.detail);
                });
              });

              // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名
              wx.error(function (err) {
                console.log("error", err);
              });
            }
          }
        })

        // var launchBtn = document.getElementById("launch-btn");
        // launchBtn.addEventListener("ready", function (e) {
        //   console.log("开放标签 ready");
        // });
        // launchBtn.addEventListener("launch", function (e) {
        //   console.log("开放标签 success");
        // });
        // launchBtn.addEventListener("error", function (e) {
        //   console.log("开放标签 fail", e.detail);
        // });

        // wx.config({
        //   // debug: true, // 调试时可开启
        //   appId: "", // 小程序APPID
        //   timestamp: 0, // 必填,填任意数字即可
        //   nonceStr: "nonceStr", // 必填,填任意非空字符串即可
        //   signature: "signature", // 必填,填任意非空字符串即可
        //   jsApiList: ["chooseImage"], // 必填,随意一个接口即可
        //   openTagList: ["wx-open-launch-weapp"], // 填入打开小程序的开放标签名
        // });
      } else if (isDesktop) {
        // 在 pc 上则给提示引导到手机端打开
        var containerEl = document.getElementById("desktop-web-container");
        containerEl.classList.remove("hidden");
        containerEl.classList.add("full", "desktop-web-container");
      } else {
        var containerEl = document.getElementById("public-web-container");
        containerEl.classList.remove("hidden");
        containerEl.classList.add("full", "public-web-container");

        // 云函数
        // 因未开通云开发环境,此处不做处理
        // var c = new cloud.Cloud({
        //   identityless: true, // 必填,表示是未登录模式
        //   resourceAppid: "小程序 AppID", // 资源方 AppID
        //   resourceEnv: '云开发环境 ID', // 资源方环境 ID
        // });
        // await c.init();
        // window.c = c;
        // var buttonEl = document.getElementById("public-web-jump-button");
        // var buttonLoadingEl = document.getElementById("public-web-jump-button-loading");
        // try {
        //   await openWeapp(() => {
        //     buttonEl.classList.remove("weui-btn_loadin");
        //     buttonLoadingEl.classList.add("hidden");
        //   })
        // } catch (error) {
        //   buttonEl.classList.remove("weui-btn_loadin");
        //   buttonLoadingEl.classList.add("hidden");
        //   throw error;
        // }
      }
    });

    async function openWeapp(onBeforeJump) {
      console.log("未开通云开发环境", onBeforeJump);
      // 因未开通云开发环境,此处不做处理
      // var c = window.c;
      // const res = await c.callFunction({
      //   name: "public",
      //   data: {
      //     action: "getUrlScheme",
      //   },
      // });
      // console.warn(res);
      // if (onBeforeJump) {
      //   onBeforeJump();
      // }
      // location.href = res.result.openlink;
    }
  </script>
</body>
</html>

Error message

(1) Not set in "JS interface security domain name"

40575202307261047364650.png

Tips for success

(1) WeChat developer tools

f8c88202307261047471808.png

(2) Real device: there will be the name of the applet to be opened

151c1202307261048019614.png

Guess you like

Origin blog.csdn.net/weixin_64051447/article/details/131938635