閱讀245 返回首頁    go 阿裏雲 go 技術社區[雲棲]


關於webview調用js出現has no method 'toString'

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

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


Android4.2及以後,注入步驟如下:
  1.   
  1. webview.getSetting().setJavaScriptEnable(true);  
  2. class JsObject {  
  3.     @JavascriptInterface  
  4.     public String toString() { return "injectedObject"; }  
  5.  }  
  6.  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  ><span >@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 ><span  > </span><span  >class</span><span  > </span><span  >JsObject</span><span  > </span><span  >{</span><span  >
    </span><span  >@JavascriptInterface</span><span  >
    </span><span  >public</span><span  > </span><span  >String</span><span  > toString</span><span  >()</span><span  > </span><span  >{</span><span  > </span><span  >return</span><span  > </span><span  >"injectedObject"</span><span  >;</span><span  > </span><span  >}</span><span  >
 </span><span  >}</span><span  >
 webView</span><span  >.</span><span  >addJavascriptInterface</span><span  >(</span><span  >new</span><span  > </span><span  >JsObject</span><span  >(),</span><span  > </span><span  >"injectedObject"</span><span  >);</span><span  >
 webView</span><span  >.</span><span  >loadData</span><span  >(</span><span  >"</span><span  >"</span><span  >,</span><span  > </span><span  >"text/html"</span><span  >,</span><span  > </span><span  >null</span><span  >);</span><span  >
 webView</span><span  >.</span><span  >loadUrl</span><span  >(</span><span  >"javascript:alert(injectedObject.toString())"</span><span  >);</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

最後更新:2017-04-03 07:57:13

  上一篇:go Netty係列之Netty可靠性分析
  下一篇:go 【方法3:Perl版本】刪除Map中Value重複的記錄,並且隻保留Key最小的那條記錄