34

リクエストを(ホワイトリストを使用して)フィルタリングし、カスタムを使用するAndroidアプリケーションを開発していますSSLSocketFactory。このために、私はカスタムを開発し、メソッドWebViewClientをオーバーライドしました。shouldInterceptRequestGETリクエストをフィルタリングして使用することはSocketFactoryできますが、POSTリクエストをインターセプトすることはできません。

それで、POSTリクエストをインターセプトする方法はありWebViewますか?

shouldInterceptRequestメソッドのコードは次のとおりです。

public final WebResourceResponse shouldInterceptRequest(WebView view, String urlStr) {
    URI uri = URI.create(urlStr);
    String scheme = uri.getScheme();
    // If scheme not http(s), let the default webview manage it
    if(!"http".equals(scheme) && !"https".equals(scheme)) {
        return null;
    }
    URL url = uri.toURL();

    if(doCancelRequest(url)) {
        // Empty response
        Log.d(TAG, "URL filtered: " + url);
        return new WebResourceResponse("text/plain", "UTF-8", new EmptyInputStream());

    } else {
        Log.d(TAG, "URL: " + url);

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("User-Agent", mSettings.getUserAgentString());

        // Configure connections
        configureConnection(conn);

        String mimeType = conn.getContentType();
        String encoding = conn.getContentEncoding();

        if(mimeType != null && mimeType.contains(CONTENT_TYPE_SPLIT)) {
            String[] split = mimeType.split(CONTENT_TYPE_SPLIT);
            mimeType = split[0];

            Matcher matcher = CONTENT_TYPE_PATTERN.matcher(split[1]);
            if(matcher.find()) {
                encoding = matcher.group(1);
            }
        }

        InputStream is = conn.getInputStream();
        return new WebResourceResponse(mimeType, encoding, is);
    }
}
4

6 に答える 6

7

私は数日前に同じ問題に直面していました。

だから私はそれを解決するライブラリを構築しました:

https://github.com/KonstantinSchubert/request_data_webviewclient

XMLHttpRequest リクエストの POST/PUT/... ペイロードを含むカスタム WebResourceRequest を持つ WebViewClient です。

ただし、フォームやその他の種類のリクエストソースでは機能しません。

このハックは、基本的に、XMLHttpRequest 呼び出しをインターセプトするスクリプトを HTML に挿入することによって機能します。post/put/... コンテンツを記録し、android.webkit.JavascriptInterface. shouldInterceptRequestそこで、メソッドが Android によって呼び出されるまで、リクエストは隠蔽されます...

于 2017-08-12T23:58:07.170 に答える
0

POST の代わりに GET を使用します。

既知の問題: http://code.google.com/p/android/issues/detail?id=9122

ここでも回答されました: Android - API レベル 4 の Android WebViewClient でフォーム POST をインターセプトする方法

于 2012-12-19T20:56:17.890 に答える
0

上記のスレッドhttp://code.google.com/p/android/issues/detail?id=9122に私の答えの1つがあり ます

コメント #31を参照してください

私が見る私の解決策の警告のいくつかは次のとおりです。

  1. 異なる Webkit に対して異なる実装を持つ xmlhttprequest プロトタイプに依存関係を置きます。
  2. URL でのポスト リクエストのデータ送信におけるセキュリティ上の問題。しかし、暗号化メカニズムを使用してそれを解決できると思います。
  3. 投稿するデータが大きい場合、一部のブラウザで URL の長さの問題が発生する

それとは別に、別のハックな方法でこの問題を解決しているように見えるこの github リポジトリを見つけました。コードを調べましたが、実装してテストする時間がありませんでした。しかし、試してみる価値があります。

于 2015-07-15T05:53:39.820 に答える
-1

送信する前に入力値を取得できます
https://github.com/henrychuangtw/WebView-Javascript-Inject

ステップ 1 : JavaScript で呼び出すクラスを作成する

class MyJavaScriptInterface
{
    @JavascriptInterface
    public void processHTML(String html)
    {
        //called by javascript
    }
}


ステップ 2 : JavaScript のインターフェイスを登録する

webview1.getSettings().setJavaScriptEnabled(true);
webview1.addJavascriptInterface(new MyJavaScriptInterface(), "MYOBJECT");


ステップ 3 : JavaScript をページに挿入する

webview1.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);

        StringBuilder sb = new StringBuilder();
        sb.append("document.getElementsByTagName('form')[0].onsubmit = function () {");
        sb.append("var objPWD, objAccount;var str = '';");
        sb.append("var inputs = document.getElementsByTagName('input');");
        sb.append("for (var i = 0; i < inputs.length; i++) {");
        sb.append("if (inputs[i].type.toLowerCase() === 'password') {objPWD = inputs[i];}");
        sb.append("else if (inputs[i].name.toLowerCase() === 'email') {objAccount = inputs[i];}");
        sb.append("}");
        sb.append("if (objAccount != null) {str += objAccount.value;}");
        sb.append("if (objPWD != null) { str += ' , ' + objPWD.value;}");
        sb.append("window.MYOBJECT.processHTML(str);");
        sb.append("return true;");
        sb.append("};");

        view.loadUrl("javascript:" + sb.toString());
    }

});
于 2015-08-12T02:27:02.287 に答える