WebView与Js交互

Posted by alonealice on 2017-12-19

在日常开发中我们经常会使用WebView,尤其是那些动态化要求很高的页面。而在使用WebView的过程中,又会有很多的问题。比如说WebView加载慢,内存消耗大以及和原生代码交互的问题。这篇文章就来简单讲讲WebView与Native交互的问题。

Native于 JavaScript 交互

java Native代码与 JavaScript 交互主要有3中方法:

1.使用系统方法 addJavascriptInterface 注入 java 对象来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//开启Js可用
mWebView.getSettings().setJavaScriptEnabled(true);

// 创建要注入的 Java 类
public class NativeInterface {


@JavascriptInterface
public void showToast() {
Toast.makeText(mContext, "hello", Toast.LENGTH_SHORT).show();
}

}

// WebView 注入即可
mWebView.addJavascriptInterface(new NativeInterface(this), "AndroidNative");

利用 WebViewClient 中 shouldOverrideUrlLoading

利用WebViewClient的中的shouldOverrideUrlLoading接口,拦截网页中的链接请求,通过对共同约定的url的解析,解析出需要的数据进行处理。在页面上,使用iframe来调用native代码,实现互通。

1
2
3
4
5
6
7
8
WebViewClient mWebViewClient=new WebViewClient(){

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Toast.makeText(content,url,Toast.LENGTH_SHORT).show();
return false;
}
};

利用 WebChromeClient 中的 onJsAlert、onJsConfirm、onJsPrompt 接口

利用WebChromeClient 中的 onJsAlert、onJsConfirm、onJsPrompt 接口,通过拦截页面上的弹框来实现与native层的数据交互。一般情况下,会使用onJsPrompt方法,因为该方法使用的情况最少,对其他业务的影响也最小。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
WebChromeClient mWebChromeClient=new WebChromeClient(){
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}

@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
return super.onJsConfirm(view, url, message, result);
}

@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
return super.onJsPrompt(view, url, message, defaultValue, result);
}
};

Js 注入漏洞

通过注入方式来实现 WebView 和 JS 交互会带来相应的安全问题。在早期的android版本中,native可被调用的方法不需要添加@JavascriptInterface即可被调用,这就导致代码会被远程调用。

已知漏洞:

1、CVE-2012-6636,揭露了 WebView 中 addJavascriptInterface 接口会引起远程代码执行漏洞;
2、CVE-2013-4710,针对某些特定机型会存在 addJavascriptInterface API 引起的远程代码执行漏洞;
3、CVE-2014-1939 爆出 WebView 中内置导出的 “searchBoxJavaBridge_” Java Object 可能被利用,实现远程任意代码;
4、CVE-2014-7224,类似于 CVE-2014-1939 ,WebView 内置导出 “accessibility” 和 “accessibilityTraversal” 两个 Java Object 接口,可被利用实现远程任意代码执行。

解决方法:

1、Android 4.2 以下不要在使用 JavascriptInterface方式,4.2 以上需要添加注解 @JavascriptInterface 才能调用。

2、在创建 WebView 时,使用 removeJavascriptInterface 方法将系统注入的 searchBoxJavaBridge_ 对象删除。

3、当系统辅助功能服务被开启时,在 Android 4.4 以下的系统中,由系统提供的 WebView 组件都默认导出 ”accessibility” 和 ”accessibilityTraversal” 这两个接口,这两个接口同样存在远程任意代码执行的威胁,同样的需要通过 removeJavascriptInterface 方法将这两个对象删除。

1
2
3
super.removeJavascriptInterface("searchBoxJavaBridge_");
super.removeJavascriptInterface("accessibility");
super.removeJavascriptInterface("accessibilityTraversal");

参考资料

Android WebView 全面干货指南

H5与Native交互之JSBridge技术