必须由原生App在WebView初始化时注入JSBridge,uni-app H5自身无桥接能力;初始参数应通过URL Query传递并立即解析;原生调用H5函数需等待UniAppJSBridgeReady事件且使用统一回调入口。
uni-app H5被原生App嵌套时,怎么让H5能调用原生能力?
必须靠原生侧主动注入 jsbridge,uni-app生成的h5本身不自带桥接能力——它只是普通网页,没权限直接访问相机、相册或 toast。原生app(android/ios)得在 webview 初始化时,把封装好的原生方法挂到 window 上,比如 window.android.share 或 window.webkit.messagehandlers.scan。
常见错误现象:
• H5里调用 window.android?.share() 报错 undefined
• uni.postMessage 在原生WebView里完全没反应
• iOS上 window.webkit.messageHandlers 是空对象
- 确认原生是否真的执行了 JS 注入(Android 用
addJavascriptInterface,iOS 用WKScriptMessageHandler+configuration.userContentController.add) - 注入时机必须在 WebView 完成加载前,且不能晚于
UniAppJSBridgeReady事件触发 - Android 4.2+ 需给注入接口加
@JavascriptInterface注解,否则方法不可见 - iOS 要关闭
allowsInlineMediaPlayback等干扰项,避免 WKWebView 拦截 message 事件
uni-app H5如何接收原生App传来的初始参数(如 token、user_id)?
别依赖 localStorage 或 sessionStorage——原生 App 启动 WebView 时还没执行 JS,这些存储是空的。最稳的方式是拼 URL Query 参数,然后在 H5 里解析 location.search。
使用场景:
• 登录态透传(token=abc123)
• 用户身份标识(uid=888)
• 渠道来源(channel=wechat)
- 原生侧打开 WebView 时,URL 必须是带参的完整地址,例如:
https://your.com/h5/index.html?token=xxx&uid=123 - H5 页面一上来就该解析:
new URLSearchParams(location.search).get('token'),不要等 DOM 加载完再取 - 避免用
document.referrer或history.state,它们在 WebView 里不稳定,尤其 Android X5 内核下常为空 - 如果参数含特殊字符(如
+、/),原生侧需URLEncoder.encode(Android)或addingPercentEncoding(iOS),H5 侧不用再 decode
原生App如何安全地调用uni-app H5里的JS函数?
不能直接 evaluateJavascript("doSomething()") 就完事——H5 页面可能还没加载完,或者 doSomething 还没定义。必须等 UniAppJSBridgeReady 事件触发后才能执行业务逻辑。
性能影响:
• 频繁调用 evaluateJavascript 会阻塞 WebView 主线程,导致页面卡顿
• 每次调用都新建 JS 上下文,开销比 postMessage 大得多
- 推荐统一入口:H5 暴露一个全局函数
window.__uniapp_bridge_callback = (data) => { ... },原生只调这个 - 原生调用前先检查函数是否存在:
if (typeof window.__uniapp_bridge_callback === 'function') { ... } - 传参建议用 JSON 字符串,避免引号嵌套出错;H5 侧用
JSON.parse(data)解析 - Android 低版本(evaluateJavascript,得降级用
loadUrl("javascript:..."),但有长度限制(约2048字符)
为什么 uni.postMessage 在原生 WebView 里收不到?
因为 uni.postMessage 本质是 window.postMessage 的封装,但它依赖 DCloud 提供的 uni.webview.js SDK 来注册监听器。如果你没手动引入这个 SDK,或者引入时机错了,消息就永远发不出去。
容易踩的坑:
• 直接在 H5 页面写 uni.postMessage(...),但没引入 SDK
• 引入了 SDK,却放在 <body> 底部,导致按钮点击时 SDK 还没加载完
• 原生 WebView 没启用 setJavaScriptEnabled(true)(Android)或没配置 WKWebViewConfiguration 允许 JS 执行(iOS)
- H5 页面
<head>中必须同步加载:<script src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script> - 确保
uni.webview.js加载完成后才绑定事件:document.addEventListener('UniAppJSBridgeReady', () => { ... }) - 原生侧要监听
message事件(AndroidWebChromeClient.onConsoleMessage不行,得用WebViewClient.shouldOverrideUrlLoading拦截自定义协议,或直接用evaluateJavascript注入监听器) - uni-app 官方
web-view组件的@message事件只适用于 uni-app 自己的 WebView,不适用于原生 App 嵌套的普通 WebView
最麻烦的其实是生命周期错位:原生 App 可能提前销毁 WebView,而 H5 还在发消息;或者 H5 页面重定向后,原生侧还往旧实例发指令。这类问题不会报错,只会静默失败,得靠日志 + 唯一 request id + 超时兜底来定位。










