現在小程序越來越普遍了,從H5網頁(要在微信瀏覽器下打開的)跳轉到相應小程序的場景也越來越多。至此微信提供了相應的微信開放標簽讓網頁開發者可安全便捷地使用微信或系統的能力,為微信用戶提供更優質的網頁體驗。
需要注意的是,微信開放標簽有最低的微信版本和最低的系統版本要求。
- 微信版本要求為:7.0.12及以上
- 系統版本要求為:iOS 10.3及以上、Android 5.0及以上
對于符合微信或系統最低版本要求但仍無法使用微信開放標簽的場景,將會在下方使用步驟中的wx.config
權限驗證成功后觸發WeixinOpenTagsError
事件告知開發者。僅無法使用微信開發標簽,JS-SDK其他功能不受影響。可通過如下方法監聽并進行回退兼容:
document.addEventListener('WeixinOpenTagsError', function (e) {
console.error(e.detail.errMsg); // 無法使用開放標簽的錯誤原因,需回退兼容。僅無法使用開放標簽,JS-SDK其他功能不受影響
});
根據目前已知的錯誤場景,回退兼容建議如下:
- iOS15底層 WebKit 接口發生變更,微信版本8.0.8以下(不包括8.0.8)無法使用開放標簽,可引導用戶升級最新版本微信;
- 開放標簽依賴Web Components方案,極少部分 Android 系統可能由于版本太低而不支持,可引導用戶升級系統固件。
H5網頁跳轉小程序有如下步驟:
1.在微信公眾號(已認證的服務號)綁定“JS接口安全域名”
如果是公眾號身份的網頁,需要綁定安全域名。登錄微信公眾平臺進入“公眾號設置”的“功能設置”里填寫“JS接口安全域名”。
2.引入JS文件
在需要調用 JS 接口的頁面引入如下 JS 文件:http://res.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)
如需進一步提升服務穩定性,當上述資源不可訪問時,可改訪問:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)
注意:js文件必須使用1.6.0版本以上
3.通過config接口注入權限驗證配置并申請所需開放標簽
與使用 JS-SDK 配置方式相同,所有需要使用開放標簽的頁面必須先注入配置信息,并通過openTagList
字段申請所需要的開放標簽,否則將無法使用(同一個 url 僅需調用一次)。開放標簽的申請和 JS 接口的申請相互獨立,因此是可以同時申請的。
wx.config({
debug: true, // ??開啟調試模式,調用的所有 api 的返回值會在客戶端 alert 出來,若要查看傳入的參數,可以在 pc 端打開,參數信息會通過 log 打出,僅在 pc 端時才會打印
appId: '', // 必填,公眾號的唯一標識
timestamp: , // 必填,生成簽名的時間戳
nonceStr: '', // 必填,生成簽名的隨機串
signature: '',// 必填,簽名
jsApiList: [], // 必填,需要使用的 JS 接口列表
openTagList: [] // 可選,需要使用的開放標簽列表,例如['wx-open-launch-app']
});
4.通過ready接口處理成功驗證
wx.ready(function () {
// config信息驗證后會執行 ready 方法,所有接口調用都必須在 config 接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在 ready 函數中調用來確保正確執行。對于用戶觸發時才調用的接口,則可以直接調用,不需要放在 ready 函數中
});
5.通過error接口處理失敗驗證
wx.error(function (res) {
// config信息驗證失敗會執行 error 函數,如簽名過期導致驗證失敗,具體錯誤信息可以打開 config 的debug模式查看,也可以在返回的 res 參數中查看,對于 SPA 可以在這里更新簽名
});
使用說明
所使用的標簽允許提供插槽,由于插槽中模版的樣式是和頁面隔離的,因此需要注意在插槽中定義模版的樣式。插槽模版及樣式均需要通過<script type="text/wxtag-template"></script>或<template></template>
進行包裹。另外,對于具名插槽還需要通過slot
屬性聲明插槽名稱,下文標簽插槽中的 default 插槽為默認插槽,可不聲明插槽名稱。
對于標簽事件,均可通過event.detail
獲得詳細信息。如果無特殊說明,下文標簽事件說明中的返回值均指代event.detail
中的內容。
另外,需要注意以下幾點:
- 頁面中與布局和定位相關的樣式,如
position: fixed; top -100;
等,盡量不要寫在插槽模版的節點中,請聲明在標簽或其父節點上; - 對于有 CSP 要求的頁面,需要添加白名單
frame-src https://*.qq.com webcompt:
,才能在頁面中正常使用開放標簽。
開放對象
- 已認證的服務號,服務號綁定“JS接口安全域名”下的網頁可使用此標簽跳轉任意合法合規的小程序。
- 已認證的非個人主體的小程序,使用小程序云開發的靜態網站托管綁定的域名下的網頁,可以使用此標簽跳轉任意合法合規的小程序。
代碼
參考:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/staticstorage/jump-miniprogram.html
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html
<!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" >
<!-- 頁面樣式 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>
錯誤提示
(1)沒有在“JS接口安全域名”設置
成功提示
(1)微信開發者工具
(2)真機:會有要打開小程序的名字