关于webview调用js出现has no method 'toString'

在android4.2以前,注入步骤如下:

webview.getSetting().setJavaScriptEnable(true);  
class JsObject {  
 public String toString() { return "injectedObject"; }  
 }  
 webView.addJavascriptInterface(new JsObject(), "injectedObject");  

Android4.2及以后,注入步骤如下:

webview.getSetting().setJavaScriptEnable(true);  
class JsObject {  
 @JavascriptInterface 
 public String toString() { return "injectedObject"; }  
 }  
 webView.addJavascriptInterface(new JsObject(), "injectedObject");  

发现区别没?4.2之前向webview注入的对象所暴露的接口toString没有注释语句@JavascriptInterface,而4.2及以后的则多了注释语句@JavascriptInterface

经过查官方文档所知,因为这个接口允许JavaScript 控制宿主应用程序,这是个很强大的特性,但同时,在4.2的版本前存在重大安全隐患,因为JavaScript 可以使用反射访问注入webview的java对象的public fields,在一个包含不信任内容的WebView中使用这个方法,会允许攻击者去篡改宿主应用程序,使用宿主应用程序的权限执行java代码。因此4.2以后,任何为JS暴露的接口,都需要加

<span class="lit" style="color:#06666;"><span style="font-size:18px;">@JavascriptInterface</span></span>

注释,这样,这个Java对象的fields 将不允许被JS访问。

官方文档说明:

From the Android 4.2 documentation:

Caution: If you've set your targetSdkVersion to 17 or higher, you must add the @JavascriptInterface annotation to any method that you want available your web page code (the method must also be public). If you do not provide the annotation, then the method will not accessible by your web page when running on Android 4.2 or higher.

注:如果将targetSdkVersion 设置为17或者更高,但却没有给暴露的js接口加@JavascriptInterface注释,则logcat会报如下输出:

E/Web Console: Uncaught TypeError: Object [object Object] has no method 'toString'

public void addJavascriptInterface (Object object, String name)

Added in API level 1

Injects the supplied Java object into this WebView. The object is injected into the JavaScript context of the main frame, using the supplied name. This allows the Java object's methods to be accessed from JavaScript. For applications targeted to API level JELLY_BEAN_MR1 and above, only public methods that are annotated with JavascriptInterface can be accessed from JavaScript. For applications targeted to API level JELLY_BEAN or below, all public methods (including the inherited ones) can be accessed, see the important security note below for implications.

Note that injected objects will not appear in JavaScript until the page is next (re)loaded. For example:

<span style="font-size:18px;"><span class="pln" style="color:#000000;"> </span><span class="kwd" style="color:#0088;">class</span><span class="pln" style="color:#000000;"> </span><span class="typ" style="color:#66066;">JsObject</span><span class="pln" style="color:#000000;"> </span><span class="pun" style="color:#66660;">{</span><span class="pln" style="color:#000000;">
    </span><span class="lit" style="color:#06666;">@JavascriptInterface</span><span class="pln" style="color:#000000;">
    </span><span class="kwd" style="color:#0088;">public</span><span class="pln" style="color:#000000;"> </span><span class="typ" style="color:#66066;">String</span><span class="pln" style="color:#000000;"> toString</span><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;"> </span><span class="pun" style="color:#66660;">{</span><span class="pln" style="color:#000000;"> </span><span class="kwd" style="color:#0088;">return</span><span class="pln" style="color:#000000;"> </span><span class="str" style="color:#0880;">"injectedObject"</span><span class="pun" style="color:#66660;">;</span><span class="pln" style="color:#000000;"> </span><span class="pun" style="color:#66660;">}</span><span class="pln" style="color:#000000;">
 </span><span class="pun" style="color:#66660;">}</span><span class="pln" style="color:#000000;">
 webView</span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">addJavascriptInterface</span><span class="pun" style="color:#66660;">(</span><span class="kwd" style="color:#0088;">new</span><span class="pln" style="color:#000000;"> </span><span class="typ" style="color:#66066;">JsObject</span><span class="pun" style="color:#66660;">(),</span><span class="pln" style="color:#000000;"> </span><span class="str" style="color:#0880;">"injectedObject"</span><span class="pun" style="color:#66660;">);</span><span class="pln" style="color:#000000;">
 webView</span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">loadData</span><span class="pun" style="color:#66660;">(</span><span class="str" style="color:#0880;">"</span><span class="str" style="color:#0880;">"</span><span class="pun" style="color:#66660;">,</span><span class="pln" style="color:#000000;"> </span><span class="str" style="color:#0880;">"text/html"</span><span class="pun" style="color:#66660;">,</span><span class="pln" style="color:#000000;"> </span><span class="kwd" style="color:#0088;">null</span><span class="pun" style="color:#66660;">);</span><span class="pln" style="color:#000000;">
 webView</span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">loadUrl</span><span class="pun" style="color:#66660;">(</span><span class="str" style="color:#0880;">"javascript:alert(injectedObject.toString())"</span><span class="pun" style="color:#66660;">);</span></span>

IMPORTANT:

  • This method can be used to allow JavaScript to control the host application. This is a powerful feature, but also presents a security risk for applications targeted to API level JELLY_BEAN or below, because JavaScript could use reflection to access an injected object's public fields. Use of this method in a WebView containing untrusted content could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using this method in a WebView which could contain untrusted content.
  • JavaScript interacts with Java object on a private, background thread of this WebView. Care is therefore required to maintain thread safety.
  • The Java object's fields are not accessible.
Parameters

object

the Java object to inject into this WebView's JavaScript context. Null values are ignored.

name

the name used to expose the object in JavaScript

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逸鹏说道

我这么玩Web Api(二)

数据验证,全局数据验证与单元测试 目录 一、模型状态 - ModelState 二、数据注解 - Data Annotations 三、自定义数据注解 四、全局...

5386
来自专栏java一日一条

50个常见的 Java 错误及避免方法(第三部分)

当我们尝试调用带有错误参数的Java代码时,通常会产生此Java错误消息(@ghacksnews):

1543
来自专栏Kubernetes

runC源码分析——namespace

runc/libcontainer/configs/config.go中定义了container对应的Namespaces。另外对于User Namespace...

3978
来自专栏流媒体

Android平台下使用FFmpeg进行RTMP推流(视频文件推流)简介

前面已经讲到如何在Linux环境下编译FFmpeg以及在Android项目中使用,这一节就开始真正的使用FFmpeg。在Android平台下用FFmepg解析视...

6192
来自专栏Java学习网

Android中Java和JavaScript交互

Android中Java和JavaScript交互 Android提供了一个很强大的WebView控件用来处理Web网页,而在网页中,JavaScript又是...

3386
来自专栏大前端_Web

easyUI组件datagrid的二次封装

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/articl...

2803
来自专栏编码小白

tomcat请求处理分析(六)servlet的处理过程

1.1.1.1  servlet的解析过程 servlet的解析分为两步实现,第一个是匹配到对应的Wrapper,第二个是加载对应的servlet并进行数据,这...

7217
来自专栏cmazxiaoma的架构师之路

通用Mapper和PageHelper插件 学习笔记

1K3
来自专栏屈定‘s Blog

造轮子--Excel报表工具

由于公司内部之前对于excel封装操作并不是很方便,而且对于特殊的需求不是很容易满足,这个月的任务是迁移部分业务小报表顺便重构下,因此这里造个轮子,便于导入和导...

2123
来自专栏静默虚空的博客

JAVA 设计模式 享元模式

用途 享元模式 (Flyweight) 运用共享技术有效地支持大量细粒度的对象。 享元模式是一种结构型模式。 结构 ? ...

2176

扫码关注云+社区

领取腾讯云代金券