H5链接跳转小程序有2种方式:
第一种:通过微信官方提供的标签wx-open-launch-weapp,打开小程序
第二种:通过获取URL Scheme实现链接跳转小程序
官方文档https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html#21
开放范围:针对非个人主体小程序开放。
1)、wx-open-launch-weapp是在微信浏览器内的H5页面跳转小程序
2)、已认证的服务号,服务号绑定“JS接口安全域名”下的网页可使用此标签跳转任意合法合规的小程序。
所以在使用上我选择了URL Scheme方式跳转小程序
<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>
wx.config({
// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
// debug: true,
// 必填,公众号的唯一标识
appId: data.data.appId,
// 必填,生成签名的时间戳
timestamp: data.data.timestamp,
// 必填,生成签名的随机串
nonceStr: data.data.nonceStr,
// 必填,签名
signature: data.data.signature,
// 必填,需要使用的JS接口列表,且任意填写
jsApiList: ['scanQRCode'],
// 可选,需要使用的开放标签列表,wx-open-launch-weapp 指H5跳转小程序 wx-open-launch-app 指H5跳转app
openTagList: ["wx-open-launch-weapp"],
wx.ready(function () {
var btn = document.getElementById('launch-btn');
// launch 用户点击跳转按钮并对确认弹窗进行操作后触发
btn.addEventListener('launch', function (e) {
console.log(e,'success');
});
// error 用户点击跳转按钮后出现错误
btn.addEventListener('error', function (e) {
console.log(e.detail,'fail');
});
});
wx.error(function (res) {
console.log(res, 'error');
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名
});
官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/url-scheme.html
开放范围:针对非个人主体小程序开放。
在2022年4月11日以前可以在小程序公众平台生成永久的URL Scheme
但是在2022年4月11日之后就不在支持生成URL Scheme
只能通过token去生成URL Scheme
1、通过小程序appid和secret密钥获取AccessToken
2、通过AccessToken获取URL Scheme(配置路径和参数)
完整代码
<template>
<div class="container">
<img class="logo" src="./nyLogo.png" alt="">
<div class="yh-name">实惠商城</div>
<div class="miniprogram"><img src="./miniprogram.svg" alt="">小程序</div>
<van-button class="open-miniprogram-btn" color="#58BE6B" block type="primary" @click="goMiniProgram">获取</van-button>
</div>
</template>
<script>
import {
Button,
} from 'vant';
import axios from 'axios'
export default {
name: "RegisterInfo",
components: {
[Button.name]: Button,
},
data() {
},
computed: {},
mounted: function () {},
watch: {
'formData.cardType': function () {
this.formData.cardno = ''
}
},
methods: {
goMiniProgram(){
// 获取AccessToken: auth.getAccessToken
axios({
url: '/cgi-bin/token?grant_type=client_credential&appid=wx222222222222222222222&secret=22222222333333333444444',
method: 'get'
}).then(res => {
// 获取URLscheme
axios({
url: `/wxa/generatescheme?access_token=${res.data.access_token}`,
method: 'post',
data: {
"is_expire": true,
"expire_time": new Date().getTime(),
"jump_wxa": {
//path为需要跳转的小程序路径
"path": '/',
//要打开的小程序版本。正式版为"release",体验版为"trial",开发版为"develop"。
"env_version": 'trial',
//参数跳转过去携带的参数,最大1024个字符,只支持数字,大小写英文以及部分特殊字符
"query": ''
}
}
}).then(ret => {
if (ret.data.errcode === 0) {
location.href = ret.data.openlink
}
})
})
}
},
}
</script>
<style scoped lang="less">
html,body{
height: 100%;
}
.container {
height: 100%;
padding: 0.32rem;
text-align: center;
}
.container .logo{
width: 1.5rem;
height: 1.5rem;
display: inline-block;
margin-top: 30%;
}
.container .yh-name{
font-size: 0.4rem;
color: #333;
padding: 0.2rem;
}
.container .miniprogram{
font-size: 0.32rem;
color: #999;
padding: 0.2rem;
}
.container .miniprogram img{
width: 0.32rem;
height: 0.32rem;
}
.open-miniprogram-btn{
width: 4rem;
height: 0.8rem;
background-color: #58BE6B;
color: #fff;
border: none;
font-size: 0.32rem;
margin: 40% auto 0;
}
</style>
由于appid和secret写在前端,存在暴露的情况,不安全,所以改到了后端获取token,获取URL Scheme
调后端接口,获取URL Scheme,通过location.href实现跳转
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>实惠商城</title>
<!--移动端适配-->
<script>
!function(){var a="@charset \"utf-8\";html{color:#000;background:#fff;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}html *{outline:0;-webkit-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}html,body{font-family:sans-serif}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{margin:0;padding:0}input,select,textarea{font-size:100%}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}abbr,acronym{border:0;font-variant:normal}del{text-decoration:line-through}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:500}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:500}q:before,q:after{content:''}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}a:hover{text-decoration:underline}ins,a{text-decoration:none}",b=document.createElement("style");if(document.getElementsByTagName("head")[0].appendChild(b),b.styleSheet)b.styleSheet.disabled||(b.styleSheet.cssText=a);else try{b.innerHTML=a}catch(c){b.innerText=a}}();!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("灏嗘牴鎹凡鏈夌殑meta鏍囩鏉ヨ缃缉鏀炬瘮渚 ");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=(a.navigator.appVersion.match(/android/gi),a.navigator.appVersion.match(/iphone/gi)),q=a.devicePixelRatio;i=p?q>=3&&(!i||i>=3)?3:q>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var r=e.createElement("div");r.appendChild(g),e.write(r.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));
</script>
<script src="./axios.min.js"></script>
<script src="jquery-2.2.4.min.js"></script>
<style>
</style>
</head>
<body>
<div class="container" id="result">
</div>
</body>
<script>
$(function () {
var urlStr = window.location.href.split('?')[1];
var query = encodeURIComponent(urlStr);//携带参数
var expire_time = new Date().getTime();
axios({
url: 'https://xxxxx/WxAgentWeb/IMServlet?flag=2&path=/pages/index/index&env_version=trial&query=' + query + '&expire_time=' + expire_time,
method: 'get'
}).then(ret => {
var reqData = JSON.parse(ret.data.data);
if ('0' == reqData.errcode) {
location.href = reqData.openlink;
} else {
alert(reqData.errmsg);
}
}).catch(err => {
alert(err);
})
});
</script>
</html>