使用需满足硬性条件:app端src必须为http(s)地址,小程序强制https;通信须用postmessage+@message;网页需手动引入uni.webview.js才能调用uni api;h5可考虑iframe替代。

直接用 <web-view></web-view> 组件,但必须满足几个硬性条件,否则在 App 或小程序里会白屏、404 或报错。
App 端 src 必须是 HTTP(S) 地址,不能写本地路径
App 端(iOS/Android)的 <web-view></web-view> 是原生 WebView(WKWebView / 系统 WebView),不支持 file://、uni-app:// 或相对路径。写 src="/static/page.html" 或 ./page.html 会直接失败。
- ✅ 正确做法:把 HTML 部署到 HTTP(S) 服务上,填完整地址,例如
"https://example.com/app-page.html" - ✅ 开发阶段可用
http-server启一个静态服务,再用局域网 IP 访问,如"http://192.168.1.100:8080/page.html" - ❌ 不要写
src="static/page.html"、src="../static/page.html"、src="page.html" - ⚠️ 微信小程序强制要求 HTTPS,连
http://localhost都不认,开发者工具里也不行
Vue 页面和网页通信必须用 postMessage + @message,不能直调 uni
<web-view></web-view> 和 Vue 页面完全隔离,window.uni 在网页里不存在,直接调 uni.postMessage() 会报 TypeError: cannot read property 'postMessage' of undefined。
- ✅ 网页向 Vue 发消息:用
window.webkit.messageHandlers.uniWebview.postMessage(...)(仅 App 端有效);H5 需用window.parent.postMessage(..., '*');小程序用web-view自带的postMessage方法 - ✅ Vue 向网页发消息:必须等
@ready触发后才调this.$refs.webview.postMessage(...),提前调静默失败 - ✅
@message回调中取值是event.detail.data,不是event.detail - ⚠️ 消息内容只能是可序列化对象,不能传函数、
undefined、DOM 节点或循环引用
网页里想用 uni API,得手动引入 uni.webview.js
默认情况下网页 JS 上下文里没有 uni 对象。如果网页需要跳转、获取系统信息或调用原生能力,必须显式加载 SDK。
- ✅ App/H5 环境引入:
<script src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.6.js"></script> - ✅ 小程序环境还需额外引入微信 JS-SDK:
<script src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script> - ⚠️ 引入前务必判断平台,避免 H5 加载微信 SDK 报错
- ⚠️
uni.webview.js的uni.postMessage实际仍是封装后的postMessage,底层逻辑没变,只是统一了接口
H5 端可用 iframe 替代 web-view,但要注意跨域和样式穿透
如果你只面向 H5,且嵌入的是同域页面,<iframe></iframe> 更轻量、调试更直观,<web-view></web-view> 反而多一层封装。
- ✅ 同域 iframe 可以直接访问
contentWindow,用postMessage通信更可控 - ✅ 支持
ref获取 DOM,方便动态调整宽高、滚动位置等 - ⚠️ 跨域 iframe 无法读取
contentDocument,只能靠postMessage单向通信 - ⚠️ iframe 默认有边框、滚动条,需加
frameborder="0"和 CSS 清除
最容易被忽略的是:@ready 不等于页面 JS 执行完成,它只表示 WebView 容器就绪。如果网页里有异步初始化逻辑(比如等第三方 SDK 加载完再发消息),你得在网页侧主动通知 Vue 页面“我准备好了”,而不是依赖 @ready 就立刻通信。











