开放标签说明文档
# 目录
1 概述
1.1 使用步骤
1.2 使用说明
2 开放标签
2.1 跳转小程序:wx-open-launch-weapp
2.2 跳转App:wx-open-launch-app
2.3 服务号订阅通知:wx-open-subscribe
2.4 音频播放:wx-open-audio
3 在Vue、React等框架中使用
4 附录-所有开放标签列表
# 概述
微信开放标签是微信公众平台面向网页开发者提供的扩展标签集合。通过使用微信开放标签,网页开发者可安全便捷地使用微信或系统的能力,为微信用户提供更优质的网页体验。
此文档面向网页开发者,介绍微信开放标签如何使用及相关注意事项。需要注意的是,微信开放标签有最低的微信版本要求,以及最低的系统版本要求。
- 微信版本要求为: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系统可能由于版本太低而不支持,可引导用户升级系统固件。
# 使用步骤
微信开放标签使用步骤与微信JS-SDK类似,也需要引入JS文件等步骤。如果是公众号身份的网页,需要绑定安全域名,如果是使用小程序云开发静态网站托管的小程序网页,则不需绑定安全域名即可直接使用(即跳过下面"步骤一:绑定安全域名")。
# 1. 绑定域名
登录微信公众平台进入“公众号设置”的“功能设置”里填写“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)
备注:支持使用 AMD/CMD 标准模块加载方法加载。
# 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']
});
签名算法见JS-SDK说明文档的附录,所有开放标签列表见文末的附录1。
# 4. 通过ready接口处理成功验证
wx.ready(function () {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中
});
# 5. 通过error接口处理失败验证
wx.error(function (res) {
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名
});
# 使用说明
所有开放标签都能像普通的HTML标签一样在页面中直接使用,不需要再进行额外的处理。
如果所使用的标签允许提供插槽,由于插槽中模版的样式是和页面隔离的,因此需要注意在插槽中定义模版的样式。插槽模版及样式均需要通过<script type="text/wxtag-template"></script>
进行包裹。另外,对于具名插槽还需要通过slot
属性声明插槽名称,下文标签插槽中的default插槽为默认插槽,可不声明插槽名称。
对于标签事件,均可通过event.detail
获得详细信息。如果无特殊说明,下文标签事件说明中的返回值均指代event.detail
中的内容。
另外,需要注意以下几点:
- 页面中与布局和定位相关的样式,如
position: fixed; top -100;
等,尽量不要写在插槽模版的节点中,请声明在标签或其父节点上; - 对于有CSP要求的页面,需要添加白名单
frame-src https://*.qq.com webcompt:
,才能在页面中正常使用开放标签。
# 开放标签
# 跳转小程序:wx-open-launch-weapp
用于页面中提供一个可跳转指定小程序的按钮。使用此标签后,用户需在网页内点击标签按钮方可跳转小程序。H5通过开放标签打开小程序的场景值为1167。
# 开放对象
- 已认证的服务号,服务号绑定“JS接口安全域名”下的网页可使用此标签跳转任意合法合规的小程序。
- 已认证的非个人主体的小程序,使用小程序云开发的静态网站托管绑定的域名下的网页,可以使用此标签跳转任意合法合规的小程序。
# 错误提示
若跳转时出现以下页面,表示网页绑定的服务号或小程序无权限,请检查是否符合上述开放对象条件。
# 插槽
# 事件
备注:error
事件返回值errMsg
说明如下。
# 用例
<wx-open-launch-weapp
id="launch-btn"
appid="wx12345678"
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>
# 跳转APP:wx-open-launch-app
用于页面中提供一个可跳转指定App的按钮。注意:Android平台通过开放标签跳转App,App必须接入微信OpenSDK,详细参见文档《Android微信OpenSDK接入指南》。
# 开放对象
此功能仅开放给已认证的服务号,服务号绑定“JS接口安全域名”下的网页可使用此标签跳转满足一定条件的App。在使用该标签之前,首先需要前往微信开放平台的管理中心-公众账号或小程序详情-接口信息-网页跳转移动应用-关联设置中绑定所需要跳转的App。详细配置规则参考文档《微信内网页跳转APP功能》。
# 属性
备注:对于extinfo
属性,用于携带额外信息,格式自定义,由跳转的App自⾏解析处理。对应iOS微信OpenSDK中的messageExt字段(LaunchFromWXReq.message.messageExt),或对应Android微信OpenSDK中的messageExt字段(ShowMessageFromWX.Req.message.messageExt),详细参见文档《App获取开放标签<wx-open-launch-app>中的extinfo数据》。
# 插槽
# 事件
备注:error
事件返回值errMsg
说明如下。
# 用例
<wx-open-launch-app
id="launch-btn"
appid="your-appid"
extinfo="your-extinfo"
>
<script type="text/wxtag-template">
<style>.btn { padding: 12px }</style>
<button class="btn">App内查看</button>
</script>
</wx-open-launch-app>
<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>
# 服务号订阅通知按钮:wx-open-subscribe
服务号提供在网页端设置订阅通知的能力。调起客户端服务号订阅通知界面,返回用户订阅通知的操作结果。
开放对象:已认证的服务号。服务号绑定“JS接口安全域名”下的网页可使用此标签调起订阅。
具体表现如图:
# 注意事项
- 开放标签有最低的微信版本和系统版本要求,无法渲染出订阅按钮时,开发者需自行做低版本处理。
- 一次性模板id和永久模板id不可同时使用。
- 开发者工具里支持清除授权和模拟订阅,目前为假数据模拟,实际效果请在真机调试。
# 属性
# 插槽
# 事件
# success事件属性说明
# error事件属性说明
备注:error
事件返回值errMsg
和errCode
说明如下。
# 用例
<wx-open-subscribe template="TenvU22BA1jCp4YHfYEpRuESXYReQyDuhs4vbdWA99I" id="subscribe-btn">
<script type="text/wxtag-template" slot="style">
<style>
.subscribe-btn {
color: #fff;
background-color: #07c160;
}
</style>
</script>
<script type="text/wxtag-template">
<button class="subscribe-btn">
一次性模版消息订阅
</button>
</script>
</wx-open-subscribe>
<script>
var btn = document.getElementById('subscribe-btn');
btn.addEventListener('success', function (e) {
console.log('success', e.detail);
});
btn.addEventListener('error',function (e) {
console.log('fail', e.detail);
});
</script>
# 音频播放:wx-open-audio
扩展音频标签,用于接入微信浮窗播放器。
# 开放对象
此功能仅开放给已认证的服务号,服务号绑定“JS接口安全域名”下的网页可使用此标签进行浮窗音频播放。
# 属性
<wx-open-audio
title="别找我麻烦"
singer="蔡健雅"
episode="说到爱"
src="http://xxx.xxx.com/.mp3"
cover="http://xxx.xxx.com/xxx.jpg"
></wx-open-audio>
# 插槽
该标签的视图可以理解成是一个播放按钮,因此具有以下插槽:
<wx-open-audio src="http://xxx.xxx.com/.mp3">
<script type="text/wxtag-template">
<div class="playBackground"></div>
</script>
<script type="text/wxtag-template" slot="playing">
<div class="pauseBackground"></div>
</script>
<script type="text/wxtag-template" slot="style">
<style>
.playBackground {
width: 60px;
height: 64px;
background: url("xxx");
background-repeat: no-repeat;
background-size: 100%;
cursor: pointer;
}
.pauseBackground {
width: 60px;
height: 64px;
background: url("xxx");
background-repeat: no-repeat;
background-size: 100%;
cursor: pointer;
}
</style>
</script>
</wx-open-audio>
# 实例属性
备注:error
属性说明如下。
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
console.log(audio.src);
console.log(audio.title);
console.log(audio.episode);
console.log(audio.singer);
console.log(audio.cover);
console.log(audio.error);
console.log(audio.ended);
console.log(audio.paused);
console.log(audio.duration);
console.log(audio.readyState);
console.log(audio.currentTime);
console.log(audio.playbackRate);
audio.src = 'http://xxx.xxx.com/.mp3'
audio.title = '别找我麻烦'
audio.episode = '说到爱'
audio.singer = '蔡健雅'
audio.cover = 'http://xxx.xxx.com/xxx.jpg'
audio.currentTime = 100;
audio.playbackRate = 1.0;
# 实例方法
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.load();
audio.play();
audio.pause();
# 事件
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('ready', function (event) {
// 标签初始化完成
});
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('durationchange', function (event) {
// 获取到音频长度
const state = event.detail;
console.log(state.duration);
});
audio.addEventListener('loadedmetadata', function (event) {
// 音频meta信息只有长度,因此loadedmetadata会接着马上触发
const state = event.detail;
console.log(state.duration);
});
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('canplay', function (event) {
// 可随时播放
const state = event.detail;
console.log(state.duration);
});
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('play', function (event) {
// 开始播放
});
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('pause', function (event) {
// 停止播放
});
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('timeupdate', function (event) {
const state = event.detail;
console.log(state.src); // 当前音频来源
console.log(state.title); // 当前音频标题
console.log(state.episode); // 当前专辑名称
console.log(state.singer); // 当前歌手名称
console.log(state.cover); // 当前专辑封面
console.log(state.playState); // 播放状态,'playing' | 'pause' | 'seeked'
console.log(state.paused); // 是否暂停
console.log(state.buffered); // 已缓冲位置,单位秒
console.log(state.currentTime); // 当前播放位置,单位秒
});
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('seeked', function (event) {
// 播放位置变更完成
const state = event.detail;
console.log(state.currentTime); // 变更后播放位置,单位秒
});
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('ratechange', function (event) {
// 播放位置变更完成
const state = event.detail;
console.log(state.playbackRate); // 变更后播放速率
});
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('ended', function (event) {
// 播放结束
});
// <wx-open-audio id="audio"></wx-open-audio>
const audio = document.getElementById('audio');
audio.addEventListener('error', function (event) {
// 发生错误
const error = event.detail;
console.log(error.errMsg);
// 1. play:fail(调用play方法失败)
// 2. pause:fail(调用pause方法失败)
// 3. seek:fail(设置currentTime失败)
// 4. ratechange:fail(设置playbackRate失败)
});
# 在Vue、React等框架中使用
插槽模版的内容和样式与主页面相互隔离,使用数据驱动的方式去更改插槽模版中的内容和样式将不会得到更新。
# 在Vue中使用
开放标签属于自定义标签,Vue会给予未知标签的警告,可通过配置Vue.config.ignoredElements
来忽略Vue对开放标签的检查。
<wx-open-audio
:title="title"
src="http://xxx.xxx.com/.mp3"
@canplay="canplay"
@pause="pause"
@seeked="seeked"
>
<script type="text/wxtag-template">
<button>播放</button>
</script>
</wx-open-audio>
# 在React中使用
因为不兼容合成事件,所以需要绑定原生事件。
function Audio() {
const audio = useRef(null);
useEffect(() => {
const canplay = () => {};
const pause = () => {};
const seeked = () => {};
audio.current.addEventListener('canplay', canplay);
audio.current.addEventListener('pause', pause);
audio.current.addEventListener('seeked', seeked);
return () => {
audio.current.removeEventListener('canplay', canplay);
audio.current.removeEventListener('pause', pause);
audio.current.removeEventListener('seeked', seeked);
};
}, []);
return (
<wx-open-audio
ref={audio}
title="别找我麻烦"
src="http://xxx.xxx.com/.mp3"
>
<script type="text/wxtag-template">
<button>播放</button>
</script>
</wx-open-audio>
);
}
# 附录-所有开放标签列表
<wx-open-launch-weapp>
<wx-open-launch-app>
<wx-open-subscribe>
<wx-open-audio>