文章出處

Native/Webview bridge for Hybrid

安裝

npm i --save webview-bridge

特點

  • 支持自定義app URL scheme
  • 支持多種處理方式(全部涵蓋)
  • 支持Promise處理回調

使用

import Bridge from 'hybride-webview-bridge';

// 如果客戶端沒有使用URL scheme,則不需要傳遞參數
const WebViewBridge = new Bridge('mqq://');
WebViewBridge.call(); // 將會喚起手機版qq軟件

/**
 * 調用原生方法
 * @param  {String} method 方法名
 * @param  {Object} params 參數
 * @return {Promise}       當收到原生方法執行的返回結果時resolve
 */
// WebViewBridge.call(method, params);

// for instance
WebViewBridge.call('getUserInfo').then(res => {
    // handle response info
});

// for instance
WebViewBridge.call('getLocation', { CacheMode: 0 }).then(res => {
    // handle response info
});

要求(原理)

1、如果ios開發在ios8及以上系統使用postMessage,請支持js變量window.webkit.messageHandlers.WebViewBridge,內部實現如下:

window.webkit.messageHandlers.WebViewBridge.postMessage(JSON.stringify({
    method: 'getLocation',
    params: {
        CacheMode: 0,
    },
}));

2、客戶端注入全局對象 WebViewBridge,并實現call方法,js用法如下:

window.WebViewBridge.call('getLocation', JSON.stringify({
    CacheMode: 0,
}));

如果沒有實現call方法,則js內部會調用被注入WebViewBridge對象方法,如:

window.WebViewBridge.getLocation(JSON.stringify({
    CacheMode: 0,
}));

3、如果不支持postMessage發送消息,也沒有注入全局js對象,最一種就是使用URL scheme了,客戶端url攔截處理,這種方式需要使用setTimeout延時處理,避免后者覆蓋前者(同時調用多次)協議地址類似如下:

const msg = decodeURIComponent(JSON.stringify({
    method: 'getLocation',
    params: {
        CacheMode: 0,
    },
}));
const URLScheme = `qq://${msg}`;

callback 回調

當調用 WebViewBridge.call('getUserInfo')成功,要求客戶端調用前端 WebViewBridgeCallback 方法進行響應,源碼如下:

/**
 * 調用原生客戶端方法后執行的回調函數
 * @param  {String} method 方法名
 * @param  {Object|String} res 回調響應信息
 */
window.WebViewBridgeCallback = (method, res) => {
    if (typeof res === 'String') {
        res = JSON.parse(res);
    }
    window.WebViewBridge.receiveResponse(method, res);
};

知識點擴充

android

安卓通過addJavaScriptInterface方法注入Java對象到js上下文對象window中,由于4.2以下版本中,該方法有漏洞, 解決該漏洞的方法有兩種,第一種通過URL scheme解決,第二種通過如下方案解決:

webview.loadUrl("javascript:if(window.WebViewBridge === undefined) { window.WebViewBridge = { call: function(jsonString) { window.prompt(jsonString); }}};");

在webview中通過loadUrl定義一個window.WebViewBridge及call通用方法,方法體內執行了window.prompt,然后在WebChromeClient類中處理onJsPrompt,設置攔截規則,onJsPrompt返回true,將不處理dialog;

推薦文章:安卓Webview

ios

ios8系統及以上版本可以通過注入 window.webkit.messageHandlers.XXX.postMessage方法,我們可以使用這個方法直接向 Native 層傳值,非常方便。 推薦文章:postMessage技術 ios官方webkit網站

ios7開始,還可以使用javascriptcore注入Java對象到js上下文對象window中 最后一種 ios也支持URL scheme

推薦文章:WKWebview相關

 

個人微信公眾號:

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()