最近参与开发h5 项目,在从natvie 跳转的时候,h5 的首页包裹着webView,我开始比较关心native 和 h5 是如何交互的
在js 封装的库里,我看到
window.MobileNavi && MobileNavi.configBtn(JSON.stringify(params));
代码实现的功能是配置title 的样式,这里是通过 h5 去调用android native 的代码,configBtn() 和 Mobilenavi 分别是 android 中对应的方法 和 对象
那么 h5 和 android 是如何关联起来的呢? 我看下android 这边是如何实现的
对于原生的这边,主要是webView 来控制管理,通过注册js 桥对象来实现
// 导航栏新接口
addJavascriptInterface(new MobileNavi(this));
MobileNavi 类,是处理configBtn 的,那我们来看下configBtn 的实现方式
@JavascriptInterface
public void configBtn(final String configParam) {
if (webUiBinder.getWebView().getNavigatorHolder() != null) {
webUiBinder.getWebView().post(new Runnable() {
@Override
public void run() {
webUiBinder.getWebView().getNavigatorHolder().configBtn(configParam);
}
});
}
}
当我们在native 端调用js 的方式有loadUrl() 和 evaluateJavascript() 方式,如上代码,如果我们在js 调用 native 方法后,再次和js 进行交互这时候 如果使用laodUrl 的方式,还是要通过
webView.loadUrl("javascript:" + jsCallBack + "('" + jsonStr + "');");
的方式,将 jsCallBack 回调注册到js,在window 中生成映射对象,名称为jsCallBack 的方法去处理js 层的回调。
关于js 和native 通讯的原理,这个地方的资料,说的都比较模糊
iframe 原理
iframe
元素可以在当前网页之中,嵌入其他网页。每个iframe
元素形成自己的窗口,即有自己的window
对象。iframe
窗口之中的脚本,可以获得父窗口和子窗口。但是,只有在同源的情况下,父窗口和子窗口才能通信;如果跨域,就无法拿到对方的DOM。
比如,父窗口运行下面的命令,如果iframe
窗口不是同源,就会报错。
document.getElementById("myIFrame").contentWindow.document
// Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.
上面命令中,父窗口想获取子窗口的DOM,因为跨域导致报错。
反之亦然,子窗口获取主窗口的DOM也会报错。
window.parent.document.body
// 报错
这种情况不仅适用于iframe
窗口,还适用于window.open
方法打开的窗口,只要跨域,父窗口与子窗口之间就无法通信。
如果两个窗口一级域名相同,只是二级域名不同,那么设置上一节介绍的document.domain
属性,就可以规避同源政策,拿到DOM。
我们看到这个方法是加了 @JavascriptInterface 注解相比较客户端调用 JS 的方法,JS 调用客户端的方法就比较多了,简单归类一下其实可以分为注入映射和方法劫持两种。注入映射主要是使用官方提供的 addJavascriptInterface()
方法将 Java 对象和 JS 对象进行映射。而方法劫持则是利用 JS 的一些系统方法调用会存在 Java 的事件回调,然后在回调中进行事件劫持,从而执行客户端方法。
注意: addJavascriptInterface有风险,hacker可以通过反编译获取Native注册的Js对象, 然后在页面通过反射Java的内置静态类,获取一些敏感的信息和破坏
参考资料:
1 https://blog.youkuaiyun.com/carson_ho/article/details/64904691
Android:你要的WebView与 JS 交互方式 都在这里了
2 https://www.jianshu.com/p/3c94ae673e2a
Android:这是一份全面 & 详细的Webview使用攻略
参考资料
3 https://www.jianshu.com/p/fd61e8f4049e
Android WebView 全面干货指南
4 https://juejin.im/post/5a30f5195188253ee45b7048
深度学习js与安卓的交互以及WebView的那些坑
5 https://juejin.im/post/5a806fba6fb9a06348535c9f
Android:是时候掌握WebView与Js的交互技术了
6 https://www.jianshu.com/p/61da3baae535
addJavascriptInterface源码分析
7 https://blog.youkuaiyun.com/xiyan_19/article/details/49507413
Android WebView中JAVA与JS之间的传递(一)
8 https://blog.youkuaiyun.com/typename/article/details/40425275
Android 各个版本WebView