最近忙于工作,疏于技术分享,甚是惶恐,今日便记录期中问题,可能其他人也会遇到,水平有限,纠错补漏,受之欣然。
我们的业务场景有APP和小程序,现有H5,其业务需根据运行环境定制处理。要判断H5是否是运行在APP环境,肯定是需要APP提供方法的,这里的原理是:
1、APP 提供JSBridge,在webview加载H5前注入到webview内(有一些APP可能是异步注入JSBridge,此时是要等到注入ready以后才能访问到JSBridge);
2、H5通过JSBridge调用APP提供判断环境的方法即可。
APP是我们自己的,我们拥有控制权,但小程序呢?我们又如何知道H5运行在微信小程序环境?找微信团队直接沟通是不可能的。其实,技术原理底层都是相通的,在小程序也是同样道理。
判断H5是运行在小程序环境有三种方法(任选其一):
1、通过window.__wxjs_environment变量判断,建议在WeixinJSBridgeReady回调中使用;
2、使用JSSDK 1.3.2提供的getEnv接口;
3、从微信7.0.0开始,判断userAgent中包含miniProgram字样。
第一种方法:window.__wxjs_environment
是不是有点类似APP环境判断的方法。是的,原理是一样的。微信小程序web-view组件其实可以理解为APP的webview,又或者可以理解为浏览器里的每个标签页。小程序web-view组件在加载H5时,也会注入一个JSBridge(微信小程序提供的JSBridge叫WeixinJSBridge)这个WeixinJSBridge本质上是一个JavaScript对象,它提供了一些可以跟微信APP交换信息的方法。
这里最好是在WeixinJSBridgeReady回调中使用,代码如下:
// 检查微信小程序环境function checkWxMiniProgramEnv() { return new Promise(function (resolve) { const ready = () => { return resolve(window.__wxjs_environment === 'miniprogram') } if (!window.WeixinJSBridge || !WeixinJSBridge.invoke) { document.addEventListener('WeixinJSBridgeReady', ready, false) setTimeout(ready, 3000) //非微信小程序环境,要结束promise } else { ready() } })}// 回调function callback(isWxMiniprogramEnv) { alert(`这${isWxMiniprogramEnv ? '是' : '不是'}微信小程序环境`)}console.log('window.WeixinJSBridge : ', window.WeixinJSBridge)console.log('window.__wxjs_environment : ', window.__wxjs_environment)checkWxMiniProgramEnv().then(callback)// 在线示例:https://codepen.io/_Rick_/pen/mdVgaRJ?editors=1010
这里有个奇怪的地方,在小程序环境运行H5时,22行和23行输出有点出乎意料:
开发者工具输出如下:
真机输出如下:
可以看到全局变量__wxjs_environment在H5加载时就已经被注入给window对象,官方建议在WeixinJSBridgeReady回调中使用,我猜测是兼容老版本的小程序基础库。
第二种方法:使用getEnv接口
wx.miniProgram.getEnv(function(res) { console.log(res.miniprogram) // true})
这种方法需要提前加载微信提供的一个JavaScript脚本,这个脚本提供了一个全局变量wx ,浏览器控制台打印看看是什么东西。
可以看到提供了一些方法,我们确实可以找到这个家伙wx.miniProgram.getEnv
看看getEnv是啥:
其实第二种方法是第一种方法的封装,底层逻辑是一样的。
第三种方法:判断userAgent中包含miniProgram字样
浏览器打印 window.navigator.userAgent
开发者工具打印 window.navigator.userAgent
真机打印 window.navigator.userAgent
确实可以通过userAgent中包含miniProgram字样来判断,但是这里是有微信版本7.0.0及以上的要求。
代码如下:
function isWxMiniProgramEnv() { return ( window.navigator.userAgent.toLowerCase().indexOf('miniprogram') > -1 )}let flag = isWxMiniProgramEnv()alert(`这${flag ? '是' : '不是'}微信小程序环境`)
总结:
1、如果只需要知道H5运行的环境,可以采用第一种;
2、如果还需要使用wx对象提供的其他方法,建议采用第二种方法。
其中第一种和第三种方法可以合并为以下方法:
// 检查微信小程序环境function checkWxMiniProgramEnv() { return new Promise(function (resolve) { if (window.navigator.userAgent.toLowerCase().indexOf('miniprogram') > -1) { return resolve(true) } const ready = () => { return resolve(window.__wxjs_environment === 'miniprogram') } if (!window.WeixinJSBridge || !WeixinJSBridge.invoke) { document.addEventListener('WeixinJSBridgeReady', ready, false) setTimeout(ready, 3000) //非微信小程序环境,要结束promise } else { ready() } })}// 回调function callback(isWxMiniprogramEnv) { alert(`这${isWxMiniprogramEnv ? '是' : '不是'}微信小程序环境`)}// 使用方式checkWxMiniProgramEnv().then(callback)// 在线示例:https://codepen.io/_Rick_/pen/bGEJzPZ
完