【Android】Web Console: Uncaught TypeError: Object [object Object] has no method 'xxx'
2015-03-20 17:24
465 查看
From :
GL(arui319)
http://blog.csdn.net/arui319
APP开发中会经常内嵌webView,有一部分功能,需要在WebView中打开web页面,然后在web页面中通过js方法回调部分native的功能。
对于web回调native的开发方式,如果不了解的话,可以参考博文《Android中Webview使用自定义的javascript进行回调》http://blog.csdn.net/arui319/article/details/7044638
最近测试发现,在某些最新机型上(4.2及以上),JS回调好像不起做用了。打开log,提示Uncaught TypeError: Object [object Object] has no method 'xxx' 。其中xxx就是web页面中写的js方法名。
仔细研究,发现是因为Android4.2及以上版本对于js的支持方式有改变导致(又是一起新版本导致的不兼容事件,最近这种事情越来越多了)。
在android4.2以前,注入步骤如下:
[java] view
plaincopy
webview.getSetting().setJavaScriptEnable(true);
class JsObject {
public String toString() { return "injectedObject"; }
}
webView.addJavascriptInterface(new JsObject(), "injectedObject");
Android4.2及以后,注入步骤如下:
[java] view
plaincopy
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暴露的接口,都需要加
官方文档说明:
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'
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
above, only public methods that are annotated with
be accessed from JavaScript. For applications targeted to API level
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:
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
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
GL(arui319)
http://blog.csdn.net/arui319
APP开发中会经常内嵌webView,有一部分功能,需要在WebView中打开web页面,然后在web页面中通过js方法回调部分native的功能。
对于web回调native的开发方式,如果不了解的话,可以参考博文《Android中Webview使用自定义的javascript进行回调》http://blog.csdn.net/arui319/article/details/7044638
最近测试发现,在某些最新机型上(4.2及以上),JS回调好像不起做用了。打开log,提示Uncaught TypeError: Object [object Object] has no method 'xxx' 。其中xxx就是web页面中写的js方法名。
仔细研究,发现是因为Android4.2及以上版本对于js的支持方式有改变导致(又是一起新版本导致的不兼容事件,最近这种事情越来越多了)。
在android4.2以前,注入步骤如下:
[java] view
plaincopy
webview.getSetting().setJavaScriptEnable(true);
class JsObject {
public String toString() { return "injectedObject"; }
}
webView.addJavascriptInterface(new JsObject(), "injectedObject");
Android4.2及以后,注入步骤如下:
[java] view
plaincopy
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: rgb(0, 102, 102);"><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 1Injects 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_MR1and
above, only public methods that are annotated with
JavascriptInterfacecan
be accessed from JavaScript. For applications targeted to API level
JELLY_BEANor
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: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">class</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">JsObject</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">@JavascriptInterface</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">public</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">String</span><span class="pln" style="color: rgb(0, 0, 0);"> toString</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"injectedObject"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> webView</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">addJavascriptInterface</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">JsObject</span><span class="pun" style="color: rgb(102, 102, 0);">(),</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"injectedObject"</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> webView</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">loadData</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">"</span><span class="str" style="color: rgb(0, 136, 0);">"</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"text/html"</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> webView</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">loadUrl</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">"javascript:alert(injectedObject.toString())"</span><span class="pun" style="color: rgb(102, 102, 0);">);</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_BEANor
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 |
相关文章推荐
- [Android] Web Console: Uncaught TypeError: Object [object Object] has no method 'xxx'
- android中java和JS互相调用,Web Console: Uncaught TypeError: Object [object Object] has no method
- [Android] Web Console: Uncaught TypeError: Object [object Object] has no method 'xxx'
- 安卓WebView报错:android uncaught typeerror object object object has no method
- [Android]通过js方法回调部分native报错 Web Console: Uncaught TypeError: Object [object Object] has no method 'xxx'
- Android js交互错误:Uncaught TypeError: Object [object Object] has no method 'xxx'
- [Android] Web Console: Uncaught TypeError: Object [object Object] has no method 'xxx'
- Android webview js 调用java方法报错"Uncaught TypeError: Object [object Object] has no method xx
- Uncaught TypeError: Object [object Object] has no method 'xxx'
- JS调用Android中的方法时出现 "Uncaught TypeError: Object [object Object] has no method
- WebView注入Java对象注意事项 [INFO:CONSOLE(475)] "Uncaught TypeError: Object [object Object] has no method
- Uncaught TypeError: Object #<Object> has no method 'addEvents' ext-all-debug异常
- 当使用JQuery的"$",抛异常Uncaught TypeError: Object #<Object> has no method 'ajax'
- sencha touch中出现JS错误Uncaught TypeError: Object [object Object] has no method 'getForm'
- ztree “Uncaught TypeError: Object # has no method 'toLowerCase'”
- Uncaught TypeError: Object #<Object> has no method 'addEvents'
- Android JS桥交互("Uncaught ReferenceError: xxx is not defined or xxx has no method")
- Uncaught TypeError: Object #<HTMLDivElement> has no method 'attr'
- Uncaught TypeError: Object #<Object> has no method 'addEvents'
- Uncaught TypeError: Object [object Object] has no method 'highcharts'