Android - how to intercept a form POST in android

2019-01-08 20:10发布

问题:

I have a WebViewClient attached to my WebView like so:

webView.setWebViewClient(new MyWebViewClient());

Here is my implementation of MyWebViewClient:

private class MyWebViewClient extends WebViewClient {

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
      webView.loadUrl(url);
      return true;
    }    
}

I give the WebView a URL to load via loadUrl(). If I have a link (a href...) in the page, my shouldOverrideUrlLoading method is called and I can intercept the link click.

However, if I have a form whose method is POST, the shouldOverrideUrlLoading method is not called.

I noticed a similar issue here: http://code.google.com/p/android/issues/detail?id=9122 which seems to suggest overriding postUrl in my WebView. However, this API is only available starting from API level 5.

What can I do if I'm on API level 4? Is there any other way to intercept form posts?

回答1:

This is known issue, that shouldOverrideUrlLoading don't catch POST. See http://code.google.com/p/android/issues/detail?id=9122 for details.

Use GET! I personally tried using POST, because I expected some limitation of GET parameters (i.e. length of URL), but I just successfully passed 32000 bytes through GET locally without any problems.



回答2:

Do you really need to use a POST? If you want to handle formdata locally, why not have a piece of javascript handle your form and interface with "native" java code using addJavascriptInterface. E.g.

WebView engine = (WebView) findViewById(R.id.web_engine);       
engine.getSettings().setJavaScriptEnabled(true); 
engine.addJavascriptInterface(new MyBridge(this), "bridge");
engine.loadUrl(...)

Your bridge can be any class basically and you should be able to access its methods directly from javascript. E.g.

public class MyBridge {

    public MyBridge(Context context) {
         // ...
    }

    public String doIt(String a, String b) {
            JSONArray result = new JSONArray();
            result.put("Hello " + a);
            result.put("Hello " + b);
            return result.toString();       
    }

Your html / javascript could look like:

<script type="text/javascript">
    $("#button").click(function() {
        var a = $("#a").val();
        var b = $("#b").val();

        var result=JSON.parse(bridge.doIt(a, b));
        // ...
    }
</script>

<input id="a"><input id="b"><button id="button">click</button>


回答3:

I think you can override onLoadResource(WebView view, String url) from WebViewClient. This function is Added in API LEVEL 1.

This function is called when WebView will load the resource specified by the given url. Resource include js, css, iframe embeded url. Code example like this:

    @Override
    public void onLoadResource(WebView view, String url) {
        if (url.indexOf("http://www.example.com") != -1 && view != null) {
            // open url in default browser
            view.stopLoading();
            view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
        }
    }