国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android WebView控件捕獲用戶輸入的信息

2020-04-11 10:49:52
字體:
來源:轉載
供稿:網友

WebView可所謂是Android中最強大的控件之一,無所不能。
于是有這么一個需求,用戶在app之中內嵌的WebView中輸入帳號密碼的時候,App需要捕獲已經輸入的帳號密碼。

當用戶輸入帳號密碼,一般情況下會進行頁面轉跳,在頁面轉跳之前執行js腳本,通過js腳本來獲取這個帳號密碼的value值。要先獲取各個元素的class值,需要解析整個html頁面,那么我們可以重寫 onLoadResource 這個方法,代碼如下:

webview.setWebViewClient(new WebViewClient() {  @Override  public boolean shouldOverrideUrlLoading(WebView view, String url) {    view.loadUrl(url);    return false;  }  @Override  public void onLoadResource(WebView view, String url) {    getHtml();    Log.e("log-->", "onLoadResource-->>" + url);  }  @Override  public void onPageFinished(WebView view, String url) {  }});

上面這個方法在加載頁面資源時會調用,每一個資源(比如圖片)的加載都會調用一次。那么我們可以在這個方法里面執行注入的js腳本
先執行addJavascriptInterface方法,將一個java對象綁定到一個js對象中,代碼如下:

public class JavaScriptInterface {    String mPasswrod;    String mUsername;    @JavascriptInterface    public void getHTML(final String html) {      if (!TextUtils.isEmpty(html)) {        saveWebViewUserData.saveUserDataWebView(webview, html);      }    }    @JavascriptInterface    public void save_password(final String password) {      if (!TextUtils.isEmpty(password)){        LogUtils.e("received from js. password = " + password);        this.mPasswrod = password;        checkData(mUsername, mPasswrod);      }    }    @JavascriptInterface    public void save_username(final String username) {      if (!TextUtils.isEmpty(username)) {        LogUtils.e("received from js. username = " + username);        this.mUsername = username;        checkData(mUsername, mPasswrod);      }    }  }webview.addJavascriptInterface(new JavaScriptInterface(), "android");  private void getHtml() {    webview.loadUrl("javascript:window.android.getHTML('<html>'+document.body.innerHTML+'</html>');");  }

那么下面這句話執行完的結果將會返回到JavaScriptInterface中getHTML方法里面。也就是說通過綁定,js代碼調用了java代碼,并將整個html作為返回值返回,執行的是saveWebViewUserData.saveUserDataWebView(webview, html);

得到了包含class的html之后,就需要依次分析了,通常來說,一般輸入帳號密碼的頁面都含有 type=”password” 字樣。先判斷這個html頁面是否含有這個字樣,如果有,那么可能就是登錄頁面。

再判斷這個頁面的id,或者是classname是否包含password啦,pwd啦,或者什么其他和密碼有關的了,這個元素肯定就是密碼框了,再過濾掉頁面中其他的button,hidden,submit,checkbox等等,剩下的那一個肯定就是用戶名了;過濾代碼如下:(這里使用jsoup解析html獲取各個document,循環遍歷剔除不需要的元素)

public void saveUserDataWebView(WebView webView, String html) {    Document document = Jsoup.parse(html);    Elements elements = document.select("input");    boolean isContainsPassword = false;    for (Element element : elements) {      String type = element.attr("type");      if ("password".equals(type)) {        isContainsPassword = true;        break;      }    }    if (!isContainsPassword) {      return;    }    for (Element element : elements) {      String className = element.className();      String type = element.attr("type");      webView.post(new Runnable() {        @Override        public void run() {          LogUtils.e("this element id is = " + element.attr("id") + " type = " + type);          String id = element.attr("id");          if (filterData(type, id)) {            int handType = handleType(type);            if (handType == NONE) {              handType = handleId(id);              if (handType == NONE) {                handleClassName(className);              }            }            switch (handType) {              case PASSWORD:                if (id==null){                }else {                  savePasswordById(id, webView);                }                break;              case USERNAME:                if (id==null){                }else {                  saveUsernameById(id, webView);                }                break;              case NONE:                break;            }          }        }      });    }  }  private int handleClassName(String className) {    if (className == null) {      return ERROR;    }    if (className.contains("password")) {      return PASSWORD;    }    if (className.contains("captcha")) {      return ERROR;    }    return USERNAME;  }  private boolean filterData(String type, String id) {    if ("captcha".equals(type)) {      return false;    } else if ("login_vcode".equals(type)) {      return false;    } else if ("button".equals(type)) {      return false;    } else if ("hidden".equals(type)) {      return false;    } else if ("submit".equals(type)) {      return false;    } else if ("checkbox".equals(type)) {      return false;    } else if ("captcha".equals(id)) {      return false;    } else if ("inp_ChkCode".equals(id)) {      return false;    } else {      return true;    }  }  private int handleId(String id) {    if (id == null) {      return NONE;    }    if (id.contains("captcha")) {      return ERROR;    }    if (id.contains("password")) {      return PASSWORD;    }    if (id.contains("Phone")) {      return USERNAME;    }    if (id.contains("username")) {      return USERNAME;    }    if (id.contains("code")) {      return ERROR;    }    return USERNAME;  }  private int handleType(String type) {    if (type == null) {      return NONE;    }    if (type.contains("tel")) {      return ERROR;    }    if (type.contains("pwd")) {      return PASSWORD;    }    if (type.contains("password")) {      return PASSWORD;    }    return NONE;  }

將他們倆的class id記錄下來,再次通過js代碼獲取到頁面的value值,調用java代碼保存下來。代碼如下:

private void saveUsernameById(String id, WebView webView) {   webView.loadUrl("javascript:window.android.save_username(document.getElementById('" + id + "').value)"); } private void savePasswordById(String id, WebView webView) {   webView.loadUrl("javascript:window.android.save_password(document.getElementById('" + id + "').value)"); }

經過上面簡單的處理,已經大致可以獲取到用戶輸入的帳號密碼了,經過測試,簡單的頁面中的帳號密碼是可以獲取到的,其他復雜的(如密碼在轉跳時清空了,又傳值到其他地方進行運算的)需要再根據不同的方案來對付了。

轉跳前先獲取整個頁面的html,用jsoup獲取頁面的所有class name,遍歷各個節點,剔除無用內容(驗證碼按鈕等),判斷密碼框在哪,剩下的可能就是帳號了,執行js代碼獲取value值。

以上就是本文的全部內容,希望大家喜歡。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 绿春县| 南城县| 兰坪| 监利县| 南阳市| 德江县| 武清区| 沂南县| 新巴尔虎左旗| 延安市| 绍兴县| 神池县| 贵德县| 镇坪县| 吴旗县| 双辽市| 苍南县| 广元市| 涞水县| 晋江市| 塘沽区| 宁阳县| 徐闻县| 永年县| 慈利县| 永昌县| 昂仁县| 新建县| 民权县| 勃利县| 肥城市| 武义县| 南京市| 汉沽区| 于都县| 临清市| 台安县| 武平县| 湖口县| 南宫市| 普定县|