更新记录

1.0.11(2026-01-16)

1.优化编译器语法

1.0.10(2026-01-02)

  1. 修复iOS打开包含target="_blank"的a标签问题

1.0.9(2026-01-02)

  1. 增加canGoForward、canGoBack接口
查看更多

平台兼容性

uni-app(3.6.15)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - 5.0
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - -

uni-app x(3.6.15)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 5.0 -

其他

多语言 暗黑模式 宽屏模式

webView加载本地或远程h5

功能

  • 加载远程网络H5、html(富文本)、加载本地H5
  • 支持iOS、Android、harmony
  • 自定义userAgent、请求头
  • 支持cookie设置、获取、删除
  • 支持火气title、url,前进,后退,刷新等
  • 与h5/js相互通讯调用传参
  • 加载失败/成功/进度回调
  • 支持alert、confirm、prompt
  • 监听Android、鸿蒙遥控器、物理键、软键盘事件

uniapp X项目请使用https://ext.dcloud.net.cn/plugin?name=wl-uts-webviewx

集成插件步骤请参考https://www.cnblogs.com/wenrisheng/p/18323027

咨询或定制请点击上面"进入交流群"按钮私聊作者


<!--  #ifdef  APP-HARMONY -->
<embed :style="'width:'+width+'px;height:'+height+'px;'" tag="webview" :options="options"
    @onevent="onEvent"></embed>
<!--  #endif -->
<!--  #ifndef  APP-HARMONY -->
<wl-uts-webview :style="'width:'+width+'px;height:'+height+'px;'" @onEvent="onEvent"
    :params="params"></wl-uts-webview>
<!--  #endif -->

使用控件的页面要用nvue

接口

总体采用业务组数的方式更新组件属性,会自动遍历执行业务

let params = {}
params.businessArray = [
    {
        business: "",
        params: {}
    }
]
let paramsStr = JSON.stringify(params)

绑定组件属性
params: paramsStr,
options: {
    params: paramsStr
},
  • 设置URL

let url = "https://www.baidu.com"

{
    business: "setUrl", // 设置链接地址
    params: { 
        url: url, // url可以是云端地址(如https://www.baidu.com),也可以是本地文件路劲(如:/xxx/xxx/xxx/index.hmtl)
        // userAgent: "xxx", // userAgent
        headers: { // 请求头
            token: "xxx"
        }
    }
}
  • 设置可访问路径,鸿蒙加载本地h5文件的时候需要设置通用访问文件路径,不然会有跨域报错,仅支持鸿蒙
let rootPath = ""
// #ifdef APP-HARMONY
rootPath = UTSWebModel.getResourcePath('/static/loginSys')
// #endif
url = "file://" + rootPath + "/index.html";
let pathList = []
pathList.push(rootPath)
pathList.push(rootPath + "/css")
pathList.push(rootPath + "/images")
pathList.push(rootPath + "/js")
{
    business: "pathAllowingUniversalAccess", // 鸿蒙加载本地h5文件的时候需要设置通用访问文件路径,不然会有跨域报错
    params: {
        pathList: pathList
    }
}
  • 获取标题title

获取结果再onEvent回调里getTitle


{
    business: "getTitle"
}
  • 获取当前url链接

获取结果再onEvent回调里getUrl


{
    business: "getUrl"
}
  • 向前

{
    business: "goForward"
}
  • 后退

{
    business: "goback"
}
  • 停止加载

{
    business: "stopLoading"
}
  • 刷新重新加载

{
    business: "reload"
}
  • 设置cookie

harmony: 本地file协议的页面里获取的cookie为空字符串,需要服务器里获取 android: 本地file协议的页面可以设置和获取cookie,但是file协议的页面里js无法读写cookie

如果加载的是本地H5文件操作cookie会有诸多问题,请使用本地httpServer插件https://ext.dcloud.net.cn/plugin?id=15876,将h5放到本地服务里,webview加载本地服务连接的方式来操作


let cookies = []
switch (uni.getSystemInfoSync().platform) {
    case 'ios': {
        cookies.push({
            name: "name",
            value: "uniappcookie",
            path: "/",
            domain: "192.168.2.46" // 域名或IP
        })
    }
    break;
    default:
    {
        cookies.push({
            value: "name=uniappcookie;Path = /;",
            url: this.localUrl
        })
    }
        break;
}

{
    business: "setCookie",
    params: {
        cookies: cookies,

    }
}
  • 获取cookie

获取结果再onEvent回调里getCookie

```javascript

{
    business: "getCookie",
    params: {
        url: this.localUrl
    }
}
  • 删除所有cookie

{
    business: "clearAllCookie"
}
  • 是否可以前进

{
    business: "canGoForward"
}

结果在onEvent里canGoForward

  • 是否可以后退

{
    business: "canGoBack"
}

结果在onEvent里canGoBack

  • uniapp调用H5 JS的函数,并获取函数返回值 如果js函数有返回值,返回值通过onJSFunReturn回调

let funParams = {};
funParams.a = 1;
funParams.b = 2;
let js = "add(" + JSON.stringify(funParams) + ")";

let params = {}
params.js = js

{
    business: "sendDataToJS",
    params: params
}

//  H5函数,注意add函数需要挂在到window节点下,即add函数必须是权限函数
function add(params) {
    alert('调用了JS addh函数:' + JSON.stringify(params));
    return {
        result: params.a + params.b
    };
}

// windows节点下的全局函数
window["add"] = (params)=>{

}
  • webview里H5 JS发送数据给nvue,会回调onEvent事件里的onJSFunReturn

var params = {};
params.msg = "你好,我是JS";
if (IOS) {
    window.webkit.messageHandlers.bridge.postMessage(params);
} else if (ANDROID) {
    var jsonStr = JSON.stringify(params);
    window.messageHandlers.bridge(jsonStr);
} else {
    // 鸿蒙这里的bridgeObj固定这个变量
    bridgeObj.bridge(JSON.stringify(params));
}

如果参数为空时,iOS需要传个空对象,防止出错,如:


if(IOS) {
   window.webkit.messageHandlers.bridge.postMessage({});
} else if (ANDROID) {
   window.messageHandlers.bridge();
}
  • 嵌入式Android系统,如Android TV,遥控器无法聚焦问题,需要加入下面3个业务,仅支持android
// 防止一些嵌入式Android定制系统无法聚焦导致Android遥控器无法控制问题
businessArray.push({
    business: "requestFocus"
})
businessArray.push({
    business: "setFocusable",
    params: {
        isFocusable: true
    }
})
businessArray.push({
    business: "setFocusableInTouchMode",
    params: {
        isFocusableInTouchMode: true
    }
})

回调事件onEvent

onEvent(event) {
    console.log("onEvent:" + JSON.stringify(event))
    let detail = event.detail
    let opt = detail.opt
    let params = detail.params
    switch (opt) {
        case "canGoForward":{
            let value = params.value    
         }
         break;
        case "canGoBack": {
            let value = params.value    
        }
        break;
        case "onLoadView": {

        }
        break;
        case "": {
            // android: "detail":{"params":{"progress":10},"opt":""}
            // 0~100
            let progress = params.progress
        }
        break;
        case "onJSData": {
            // android: "detail":{"params":"{\"msg\":\"你好,我是JS\"}","opt":"onJSData"}
            let params = detail.params
            switch (uni.getSystemInfoSync().platform) {
                case 'android':
                    // android返回的params是字符串
                    params = JSON.parse(params)
                    break;
                case 'harmonyos':
                    params = JSON.parse(params)
                    break;
                    // ios
                default:
                    break;
            }
            let msg = params.msg
            this.showToast(msg)
        }
        break;
        case "getUrl": {
            let url = params.url
            if (url) {
                this.showToast(url)
            } else {
                this.showToast("url为空")
            }
        }
        break;
        case "getTitle": {
            let title = params.title
            if (title) {
                this.showToast(title)
            } else {
                this.showToast("title为空")
            }
        }
        break;
        case "onJSFunReturn": {
            // android: "detail":{"params":{"value":"{\"result\":3}"},"opt":"onJSFunReturn"}
            // ios: "detail":{"params":{"value":{"result":3}},"opt":"onJSFunReturn"}
            if (params) {
                let value = params.value
                if (value) {
                    switch (uni.getSystemInfoSync().platform) {
                        case 'android':
                            // android返回的params是字符串
                            value = JSON.parse(value)
                            break;
                        case 'harmonyos':
                            value = JSON.parse(value)
                            break;
                            // ios
                        default:
                            break;
                    }
                    let result = value.result
                    if (result) {
                        this.showToast("函数返回:" + result)
                    }
                }

            }

        }
        break;
        case "getCookie": {
            let cookie = params.cookie
            if (cookie) {
                this.showToast(cookie)
            } else {
                this.showToast("cookie为空")
            }
        }
        break;
        case "onKey": {
            let keyCode = params.keyCode
            switch (uni.getSystemInfoSync().platform) {
                case 'harmonyos': {
                    switch (keyCode) {
                        case 17: {
                            // 音量-

                        }
                        break;
                        case 17: {
                            // 音量+
                        }
                        break;
                        default:
                            break;
                    }
                }
                break;
                case "android": {
                    switch (keyCode) {
                        case 25: {
                            // 音量-
                            let action = params.action
                            switch (action) {
                                case 0: {
                                    // 按下
                                }
                                break;
                                case 1: {
                                    // 抬起    
                                }
                                break;
                                default:
                                    break;
                            }
                        }
                        break;
                        case 24: {
                            // 音量+
                        }
                        break;
                        default:
                            break;
                    }
                }
                break;
                default:
                    break;
            }

        }
        break;
        default:
            break;
    }
},

隐私、权限声明

1. 本插件需要申请的系统权限列表:

网络

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: