微信浏览器会阻止在其中直接打开APP 所有一般需要引导用户去其他浏览器
但是如果还是想在微信浏览器直接打开APP的话可以通过 wx-open-launch-app
这个组件
这里是官方文档
需要的一些信息
提前要准备的东西
在使用这个组件之前我们需要两个appid和一个AppSecret
appid(服务号的appid和需要被打开的appid)
AppSecret(服务号的AppSecret)
申请服务号(APP和服务号绑定在一个微信开发平台上面)
服务号申请好之后设置IP白名单
和JS接口安全域名
之后按照下图进行操作,关联需要被打开的appid
这些信息设置好之后就是在浏览器中 wx-open-launch-app
这个组件
wx-open-launch-app
-
按照上面的流程绑定好js安全域名
-
引入微信sdk
<script src="http://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
- 通过config接口注入权限验证配置并申请所需开放标签
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
appId: '这里是公众号的appid', // 必填,公众号的唯一标识
timestamp: '', // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [], // 必填,需要使用的JS接口列表
openTagList: [] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
});
this.getWxSign
这里是服务器提供的一个获取jsapi_ticket
的一个接口
该接口在服务器端的需要调用微信提供的接口(无法在前端直接调用因为会跨域)
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=服务号的appid&secret=服务号的secret
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=上个地址返回的access_token&type=jsapi
获取到jsapi_ticket
之后生成wx.config方法中要用到的signature
这里是签名规则的官方文档
其中需要sha1加密
和生成随机字符串的方法
如下
sha1加密
function encodeUTF8(s) {
var i, r = [], c, x;
for (i = 0; i < s.length; i++)
if ((c = s.charCodeAt(i)) < 0x80) r.push(c);
else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F));
else {
if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode
c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000,
r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F));
else r.push(0xE0 + (c >> 12 & 0xF));
r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
};
return r;
}
// 字符串加密成 hex 字符串
function sha1(s) {
var data = new Uint8Array(encodeUTF8(s))
var i, j, t;
var l = ((data.length + 8) >>> 6 << 4) + 16, s = new Uint8Array(l << 2);
s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer);
for (t = new DataView(s.buffer), i = 0; i < l; i++)s[i] = t.getUint32(i << 2);
s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8);
s[l - 1] = data.length << 3;
var w = [], f = [
function () { return m[1] & m[2] | ~m[1] & m[3]; },
function () { return m[1] ^ m[2] ^ m[3]; },
function () { return m[1] & m[2] | m[1] & m[3] | m[2] & m[3]; },
function () { return m[1] ^ m[2] ^ m[3]; }
], rol = function (n, c) { return n << c | n >>> (32 - c); },
k = [1518500249, 1859775393, -1894007588, -899497514],
m = [1732584193, -271733879, null, null, -1009589776];
m[2] = ~m[0], m[3] = ~m[1];
for (i = 0; i < s.length; i += 16) {
var o = m.slice(0);
for (j = 0; j < 80; j++)
w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1),
t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0,
m[1] = rol(m[1], 30), m.pop(), m.unshift(t);
for (j = 0; j < 5; j++)m[j] = m[j] + o[j] | 0;
};
t = new DataView(new Uint32Array(m).buffer);
for (var i = 0; i < 5; i++)m[i] = t.getUint32(i << 2);
var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) {
return (e < 16 ? "0" : "") + e.toString(16);
}).join("");
return hex;
}
生成随机字符串
function randomString(e) {
e = e || 32;
var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",
a = t.length,
n = "";
for (i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a));
return n
}
获取签名
通过调用 后台提供的接口比如getWxSign
获取jsapi_ticket
this.getWxSign((jsapi_ticket) => {
var timestamp = String(parseInt( new Date().getTime() / 1000));
// 这里的时间戳是10位的一个字符串或者数组,不然获取的签名对不上
var nonceStr = randomString(6)
var shaBefore = decodeURIComponent(`jsapi_ticket=${jsapi_ticket}&noncestr=${nonceStr}×tamp=${timestamp}&url=${location.href.split('#')[0]}`)
// decodeURIComponent
var signature = sha1(shaBefore)
wx.config({
debug: false,
appId: '自己的服务号appid',
timestamp: timestamp,
nonceStr: nonceStr,
signature: signature,
jsApiList: [],
openTagList: ['wx-open-launch-app']
});
})
这里是校验自己生成的签名是否正确的一个地址
签名匹配上之后
必须要在IP白名单中的域名下运行程序,可以通过微信开发工具调试程序
<wx-open-launch-app style="width: 100vw;padding-bottom: 35px;" id="launch-btn" :appid="appId" :extinfo="params">
<script type="text/wxtag-template">
<style>
.nor_box {
padding: 0 15px
}
</style>
<div class="nor_box">
<div
style="width: 100%;border:none;background:linear-gradient(to bottom,#FFD000 ,#FFA400 );text-align:center;line-height:2.45rem;height:2.45rem;border-radius:0.9rem;color:white"
class=" btn">App内查看</div>
</div>
</script>
</wx-open-launch-app>
<script>
new Vue({
data(){
return {
appId:"需要被打开的app的appid(确保已经在开发平台上关联好了)",
params:JSON.stringify({}), // 这里建议把参数转化成json字符串
}
}
})
</script>
可能用的其他内容
判断是否是浏览器
var u = navigator.userAgent
var isWeixin = u.toLowerCase().indexOf("micromessenger") !== -1;
获取打开app时的参数
原生官方提供了对应的sdk(官方地址)
apicloud
api.addEventListener({
name: 'appintent'
}, function (ret, err) {
var appParam = ret.appParam;
if (appParam.wx_arguments != undefined) {
// 判断是否是在微信浏览器中打开
var arguments = JSON.parse(appParam.wx_arguments);
} else {
if (appParam && appParam.questionId) {
vm.questionList(appParam.questionId)
}
}
if (api.systemType == 'ios') {
var iosUrl = ret.iosUrl;
} else {
var sourceAppId = ret.sourceAppId;
}
});
if (api.systemType == "ios") {
var wxPlus = api.require('wxPlus');
wxPlus.addJumpFromWxListener(function (ret) {
if (ret.reqType == "launch") {
}
});
}