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

7 回复

打印的时机在哪里?提供个完整的单页面源码补充到原始问题里
我看你发的截图,不能直接运行,原始的 web 工程比较复杂,我使用了一个静态页,head 顶部加载 uni.webview.js 和 打印

<script src="./uni.webview.1.5.6.js"></script>
<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环境。

解决方案:

  1. 最简单的处理方式是添加延迟检测:
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()
    })
}
  1. 或者使用plusready事件:
document.addEventListener('plusready', () => {
    store.commit('SET_APP_ENV', true)
}, false)
回到顶部