Native/Webview bridge for Hybrid

Posted 君华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Native/Webview bridge for Hybrid相关的知识,希望对你有一定的参考价值。

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相关

 

个人微信公众号:

 

以上是关于Native/Webview bridge for Hybrid的主要内容,如果未能解决你的问题,请参考以下文章

React Native WebView 状态栏

在iOS上反应Native WebView缺少会话cookie

Appium元素定位难点:混合式的native+webview

在 React Native WebView 中加载捆绑的静态资产

Appium解决native+webview混合型APP(公众号小程序)切换webview后元素无法定位问题

React Native WebView 在某些设备上不起作用