不能。uni-app 的 web-view 在 App 端基于系统 WebView,window.uni 不可见,原生 JSBridge 不开放;仅能通过 onMessage + postMessage 经原生桥接通信,且仅限 App 端有效。

uni-app 中 web-view 能否直接调用 App 原生能力?
不能。官方 web-view 组件在 App 端(iOS/Android)是基于系统 WebView(WKWebView / Android WebView)渲染的,与 Vue 页面运行在不同进程或上下文,window.uni 对象默认不可见,原生 JSBridge 也不开放给开发者直接使用。
这意味着你在网页里写 window.uni.postMessage(...) 或 window.uni.getEnv(),在 App 内会报 TypeError: Cannot read property 'postMessage' of undefined —— 这是最常见的卡点。
真正可行的通信路径只有一条:通过 web-view 的 onMessage + postMessage 配合原生层桥接(uni-app 已封装好),且仅限「App 端」有效,H5 和小程序另有机制。
App 端实现网页向 Vue 页面发消息的正确写法
关键不是网页里调什么 API,而是网页必须先被 web-view 加载,且 Vue 页面监听了 onMessage 事件。网页侧只需调用标准的 webkit.messageHandlers.uniWebview.postMessage(iOS)或 UniWebviewAndroid.postMessage(Android),uni-app 会自动统一为 window.webkit.messageHandlers.uniWebview.postMessage 兼容写法。
- Vue 页面中:
<web-view src="https://example.com/page.html" @message="onWebMsg"></web-view> - 网页 HTML 中(无需引入 SDK):
window.webkit.messageHandlers.uniWebview.postMessage({ action: 'loginSuccess', data: { token: 'abc123' } }); -
@message回调接收的是event.detail.data,不是event.detail全量对象 - 注意:该通信只在 App 端生效;H5 下
webkit.messageHandlers不存在,需降级为postMessage+window.parent或 URL 参数传值
Vue 页面向网页发消息要等 web-view 就绪
web-view 渲染完成前调用 postMessage 会静默失败,不报错但网页收不到。必须监听 onReady 后再操作。
- 在 Vue 页面中:
<web-view ref="webview" :src="url" @ready="onWebReady" @message="onWebMsg" ></web-view>
-
onWebReady触发后,才能安全调用:this.$refs.webview.postMessage({ action: 'initConfig', data: { theme: 'dark', lang: 'zh-CN' } }); - 网页侧需监听
message事件:window.addEventListener('message', e => { console.log('received:', e.data); }); - 注意:App 端
postMessage发送的内容会被序列化为字符串再解析,复杂对象(如含函数、Date、RegExp)会丢失类型
为什么网页里 window.location.href 跳转会失效?
在 web-view 中,直接修改 window.location.href 或调用 window.open 默认会被拦截(尤其 iOS WKWebView),页面白屏或跳转失败是典型表现。
根本原因是:WKWebView 默认禁止跨域跳转,且对 location.href 的赋值做了策略限制。
- 解决方案只有两个:
① 所有跳转都走uni.navigateTo或uni.switchTab,由 Vue 页面控制路由;
② 网页内所有外链用postMessage通知 Vue 页面,再由 Vue 页面调用uni.navigateTo({ url: '/pages/web/web?url=' + encodeURIComponent(link) })拦截并新开页面 - 不要在网页里写
<a href="https://xxx">直接跳外部域名,它大概率被屏蔽 - 如果必须内嵌跳转,确保目标页同域(或配置了 WKWebView 的
navigationDelegate,但 uni-app 不开放此配置)
最易被忽略的一点:网页里的 postMessage 接收逻辑必须在 window.onload 或 DOM ready 后注册,否则可能错过 Vue 页面首次 postMessage 发来的初始化数据。

















