uni-app使用web-view内嵌h5页面在h5页面中使用uni.getEnv获取当前环境一直返回{h5:true}延迟一秒才能打印出{plus:true}
uni-app使用web-view内嵌h5页面在h5页面中使用uni.getEnv获取当前环境一直返回{h5:true}延迟一秒才能打印出{plus:true}
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Windows | 22631.4751 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
HBuilderX类型:正式
HBuilderX版本号:4.45
手机系统:Android
手机系统版本号:Android 10
手机厂商:华为
手机机型:nova6 se
页面类型:vue
vue版本:vue2
打包方式:云端
项目创建方式:HBuilderX
### 操作步骤:
```javascript
import router from './router.js'
import store from '../store'
import { loadScript } from 'src/lib/util/load-dynamic'
router.beforeEach(async (to, from, next) => {
if(store.state.isApp === null) {
const res = await loadJs()
if(res) {
await initApp()
}
}
next()
})
async function loadJs(){
const url = 'https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js'
const result = await loadScript(url)
return result === 'success'
}
function initApp(){
return new Promise((resolve) => {
try{
uni.getEnv((res) => {
console.log('打印1',JSON.stringify(res));
console.log('res.plus:',!!res.plus);
store.commit('SET_APP_ENV', !!res.plus)
resolve('success')
})
}catch(err){
resolve('failed')
}
})
}
预期结果:
打印1 {plus: true}
res.plus: true
实际结果:
打印1 {h5: true}
res.plus: false
bug描述:
uniapp使用web-view内嵌h5页面,在h5页面中使用uni.getEnv获取当前环境,一直返回{h5:true},延迟一秒才能打印出{plus:true}
如图:
打印1期望结果:{plus:true}
实际打印结果:{h5:true}
补充说明:
打印时机1:图1 在进入路由前router.beforeEach,会先引入uni.webview的js,引入成功之后,会使用uni.getEnv,判断是否处于isApp环境。在IOS中结果正常显示{plus:true}。但是安卓真机中,结果却为{h5:true}。
打印时机2:图2 进入路由后,initApp,安卓打印结果依旧为{h5:true}
打印时机3:图2 进入路由后,setTimeout延迟1秒,安卓打印结果{plus: true}
已经确定引入了uni.webview的Js。尝试在index.html<head>中引入,失败;又尝试动态引入,亦失败。
更多关于uni-app使用web-view内嵌h5页面在h5页面中使用uni.getEnv获取当前环境一直返回{h5:true}延迟一秒才能打印出{plus:true}的实战教程也可以访问 https://www.itying.com/category-93-b0.html
打印的时机在哪里?提供个完整的单页面源码补充到原始问题里
我看你发的截图,不能直接运行,原始的 web 工程比较复杂,我使用了一个静态页,head 顶部加载 uni.webview.js 和 打印
<script>
// 待触发 `UniAppJSBridgeReady` 事件后,即可调用 uni 的 API。
document.addEventListener('UniAppJSBridgeReady', function() {
console.log('333 UniAppJSBridgeReady');
// setTimeout(()=>{
console.log(4,uni.getEnv)
uni?.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
});
// },2000)
})
</script>
在 ios 模拟器上通过 web view 加载他,发现打印是及时的正常的,不需要额外的定时器。你自测提供简单页面测试,然后逐步添加业务逻辑,看打印的实际是否和简单代码有区别。
更多关于uni-app使用web-view内嵌h5页面在h5页面中使用uni.getEnv获取当前环境一直返回{h5:true}延迟一秒才能打印出{plus:true}的实战教程也可以访问 https://www.itying.com/category-93-b0.html
好的。已经在bug描述中补充说明了打印时机和代码。麻烦您再帮忙看看叭
回复 DCloud_UNI_OttoJi: 好的,谢谢您~ 我想实现先识别是app,再进入页面的效果,用document.addEventListner(‘UniAppJsBridgeReady’)实现不了这个效果吧? 只能把它套在最外层,先运行UniAppJsBridgeReady再进行整个项目的挂载?但这样会影响单纯h5页面的用户使用体验叭
回复 张脑丸儿: 你考虑绕过的方案吧,加载 web-view 携带 query 参数 ?isApp=true ,然后在页面中判断,从而忽略 uniapp 识别的过程。简单也有效
回复 DCloud_UNI_OttoJi: 好的,谢谢您~
这是一个典型的WebView环境初始化时序问题。在Android平台上,uni.webview.js的初始化需要一定时间,导致getEnv()在初始化完成前被调用。
根本原因是Android WebView的JS Bridge初始化比iOS慢。当uni.webview.js刚加载完成时,Android的plus环境可能还未完全准备好,此时调用getEnv()会先返回H5环境。
解决方案:
- 最简单的处理方式是添加延迟检测:
function initApp(){
return new Promise((resolve) => {
const checkEnv = () => {
uni.getEnv((res) => {
if(res.plus || navigator.userAgent.indexOf('Html5Plus') > -1) {
store.commit('SET_APP_ENV', true)
resolve('success')
} else {
setTimeout(checkEnv, 200)
}
})
}
checkEnv()
})
}
- 或者使用plusready事件:
document.addEventListener('plusready', () => {
store.commit('SET_APP_ENV', true)
}, false)