5月28日 03:13

什么是 JS Bridge?WebView 和原生通信有哪几种方式?

JS Bridge 是 WebView 里 JS 和原生 App 之间互相调用的通信桥梁,Hybrid App 开发中几乎离不开它。实现方式主要有三种:URL Scheme 拦截——JS 通过 iframe.src 发自定义 scheme URL(如 myapp://camera/open),原生在 shouldOverrideUrlLoading 中拦截解析并执行,只能 JS→原生单向通信,且连续调用会丢消息需要队列化;注入 API 对象——原生通过 addJavascriptInterface(Android)或 WKScriptMessageHandler(iOS)把对象注入 WebView 的 JS 上下文,JS 直接调用方法,支持双向通信和回调,是当前最主流的方式;prompt/console 拦截——JS 调 window.prompt(),原生重写 onJsPrompt() 拦截消息并解析执行,性能比 URL Scheme 好且能拿到返回值。实际项目普遍以注入 API 为主、prompt 拦截为辅的混合方案。

追问

JS Bridge 的回调机制怎么实现的?

调用时生成唯一 callbackId,和参数一起发给原生。原生处理完通过 evaluateJavaScript() 调用 JS 侧全局回调函数,把 callbackId 和结果传回来。如果原生要主动推消息给 JS,也是通过 evaluateJavaScript() 调用 JS 挂载的全局监听函数。本质是异步 request-response + publish-subscribe 混合模式。

URL Scheme 连续调用丢消息的原因和解决方案?

iframe.src 连续赋值时前一条 URL 还没被 shouldOverrideUrlLoading 拦截就被覆盖了。解法:JS 侧维护消息队列,每次只发一条,原生处理完通过回调通知 JS 发下一条。也可以改用 prompt 拦截,它是同步的不会丢。

addJavascriptInterface 有什么安全漏洞?

Android 4.2 之前,注入对象的任何方法都能被 JS 通过反射拿到 Java 层的 Runtime,执行任意系统命令。4.2 后要求方法必须加 @JavascriptInterface 注解才暴露。iOS 的 WKWebView 用 messageHandler 机制只传消息不直接暴露方法,天生更安全。实际开发中还要对传入参数做白名单校验,防止 XSS 注入调用敏感接口。

小程序和 WebView JS Bridge 有什么区别?

小程序逻辑层(JS)和渲染层(WebView)跑在不同线程,所有通信都要经过 Native 中转序列化,setData 走的就是这条通道。普通 WebView JSBridge 是同进程内通信,性能好但渲染和逻辑互相阻塞。小程序的代价是频繁 setData 序列化开销大,所以官方建议合并数据、减少调用次数。

怎么设计一个通用的 JS Bridge SDK?

定义统一协议格式:{ module, method, params, callbackId },JS 侧封装 call(method, params, callback)on(event, handler),原生侧按 module 注册 handler。兼容层先尝试注入 API,失败降级到 prompt 拦截,再失败降级 URL Scheme。加上消息队列防丢、超时重试、日志上报,就是一套生产级方案。

标签:JavaScript