最近參與開發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.csdn.net/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.csdn.net/xiyan_19/article/details/49507413
Android WebView中JAVA與JS之間的傳遞(一)
8 https://blog.csdn.net/typename/article/details/40425275
Android 各個版本WebView