it-swarm.com.de

Abfangen POST Anforderungen in einer WebView

Ich entwickle eine Android-Anwendung, die die Anfragen filtert (mit einer weißen Liste) und eine benutzerdefinierte SSLSocketFactory verwendet. Dafür habe ich eine benutzerdefinierte WebViewClient entwickelt und die shouldInterceptRequest Methode überschrieben. Ich kann meine SocketFactory mit den GET-Anforderungen filtern und verwenden, aber die POST -Anfragen kann ich nicht abfangen.

Gibt es eine Möglichkeit, die POST - Anforderungen in einer WebView abzufangen?

Hier ist der Code der shouldInterceptRequest-Methode:

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);
    }
}
28
Fab_34

Ich war vor ein paar Tagen mit demselben Problem konfrontiert.

Also baute ich eine Bibliothek, die es löst: 

https://github.com/KonstantinSchubert/request_data_webviewclient

Hierbei handelt es sich um einen WebViewClient mit einem benutzerdefinierten WebResourceRequest, der die POST/PUT/... -Nutzlast von XMLHttpRequest-Anforderungen enthält.

Es funktioniert jedoch nur für diese - nicht für Formulare und andere Arten von Anforderungsquellen.

Der Hack funktioniert im Wesentlichen durch das Einfügen eines Skripts in den HTML-Code, der XMLHttpRequest-Aufrufe abfängt. Es zeichnet den Post/Put/... Inhalt auf und sendet ihn an einen Android.webkit.JavascriptInterface. Dort wird die Anforderung so lange gespeichert, bis die shouldInterceptRequest-Methode von Android aufgerufen wird ...

3
1
Raanan

sie können den Eingabewert vor dem Absenden abrufen
https://github.com/henrychuangtw/WebView-Javascript-Inject

Schritt 1: Erstellen Sie eine Klasse, die von Javascript aufgerufen wird

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


Schritt 2: Registrieren Sie die Schnittstelle für Javascript

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


Schritt 3: Injizieren Sie Javascript in die Seite

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());
    }

});
0
HenryChuang

Ich habe eine meiner Antworten im obigen Thread http://code.google.com/p/Android/issues/detail?id=9122

Bitte sehen Sie Kommentar # 31

Einige der Vorbehalte meiner Lösung, die ich sehe, sind:

  1. Abhängig von xmlhttprequest-Prototyp, der für verschiedene Webkits unterschiedlich implementiert ist.
  2. Sicherheitsproblem beim Senden von Daten für Post-Anforderungen in URL. Aber ich denke, Sie können das durch einen Verschlüsselungsmechanismus lösen.
  3. URL-Längenproblem für einige Browser, wenn Sie große Daten veröffentlichen

Abgesehen davon habe ich dieses github repo gefunden, das dieses Problem auf andere Weise zu lösen scheint. Ich habe mir den Code angesehen, aber ich hatte keine Zeit, ihn zu implementieren und zu testen. Aber einen Versuch wert.

0
chetan pawar