Android 实测WebView获取页面的post请求参数(form,ajax)

背景

由于项目需求要获取某些网页的请求参数信息,get请求的参数拼接在url中,所以可以直接拦截url获得,但是post请求的参数信息存放在body里面,android没有提供方法直接获取,而该网页是其他第三方提供的,不方便修改网页代码来传递参数给android原生这边,所以可以通过js注入的方式来获取。

效果图

在这里插入图片描述

2022-06-30 23:05:23.808 15890-16193/com.my.demo E/zbm: 拦截到的post请求数据:
2022-06-30 23:05:23.814 15890-16193/com.my.demo E/zbm: [
        {
    
    
            "name": "action",
            "value": "prospect",
            "type": "hidden"
        },
        {
    
    
            "name": "first_name",
            "value": "萌面",
            "type": "text"
        },
        {
    
    
            "name": "last_name",
            "value": "小侠",
            "type": "text"
        },
        {
    
    
            "name": "country",
            "value": "US",
            "type": "select-one"
        },
        {
    
    
            "name": "zip",
            "value": "12345",
            "type": "tel"
        },
        {
    
    
            "name": "address",
            "value": "cupertino ca 95014",
            "type": "text"
        },
        {
    
    
            "name": "address_2",
            "value": "",
            "type": "text"
        },
        {
    
    
            "name": "city",
            "value": "Schenectady",
            "type": "text"
        },
        {
    
    
            "name": "state",
            "value": "NY",
            "type": "select-one"
        },
        {
    
    
            "name": "phone",
            "value": "(123) 458-8555",
            "type": "tel"
        },
        {
    
    
            "name": "email",
            "value": "[email protected]",
            "type": "email"
        }
    ]

关键步骤

js代码

核心js代码下载jscore
从文件中读取js代码为字符串,便于后面给webview加载

public class IOUtils {
    
    
    public static byte[] readFully(InputStream in) throws IOException {
    
    
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        for (int count; (count = in.read(buffer)) != -1; ) {
    
    
            out.write(buffer, 0, count);
        }
        return out.toByteArray();
    }
}

WebViewClient注入js代码

在页面加载完成回调onPageFinished的时候通过webview.loadUrl()将js代码注入到当前页面

public class InterceptingWebViewClient extends WebViewClient {
    
    

    private Context mContext = null;
    private WebView mWebView = null;
    private PostInterceptJavascriptInterface mJSSubmitIntercept;

    public InterceptingWebViewClient(Context context, WebView webView) {
    
    
        mContext = context;
        mWebView = webView;
        mJSSubmitIntercept = new PostInterceptJavascriptInterface(this);
        mWebView.addJavascriptInterface(mJSSubmitIntercept, "interception");

    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
    
    
        mNextAjaxRequestContents = null;
        mNextFormRequestContents = null;

        view.loadUrl(url);
        return true;
    }

    @Override
    public void onPageFinished(WebView view, String url) {
    
    
        super.onPageFinished(view, url);
        try {
    
    
        	String mInterceptHeader = new String(IOUtils.readFully(mContext.getAssets().open("jscore")));
			view.loadUrl("javascript:" + mInterceptHeader);
		}catch (Exception e){
    
    
                Log.e("zbm", "js注入失败:" + e);
		}
    }

    private PostInterceptJavascriptInterface.FormRequestContents mNextFormRequestContents = null;

    public void nextMessageIsFormRequest(PostInterceptJavascriptInterface.FormRequestContents formRequestContents) {
    
    
        mNextFormRequestContents = formRequestContents;
    }

    private PostInterceptJavascriptInterface.AjaxRequestContents mNextAjaxRequestContents = null;

    public void nextMessageIsAjaxRequest(PostInterceptJavascriptInterface.AjaxRequestContents ajaxRequestContents) {
    
    
        mNextAjaxRequestContents = ajaxRequestContents;
    }
}

js与android通信桥梁

当页面有post请求时会回调customAjax与customSubmit接口将请求参数传给原生层。

public class PostInterceptJavascriptInterface {
    
    

    private static String mInterceptHeader;
    private InterceptingWebViewClient mWebViewClient;

    public PostInterceptJavascriptInterface(InterceptingWebViewClient webViewClient) {
    
    
        mWebViewClient = webViewClient;
    }

    public class FormRequestContents {
    
    
        public String method = null;
        public String json = null;
        public String enctype = null;

        public FormRequestContents(String method, String json, String enctype) {
    
    
            this.method = method;
            this.json = json;
            this.enctype = enctype;
        }
    }

    public class AjaxRequestContents {
    
    
        public String method = null;
        public String body = null;

        public AjaxRequestContents(String method, String body) {
    
    
            this.method = method;
            this.body = body;
        }
    }

    @JavascriptInterface
    public void customAjax(final String method, final String body) {
    
    
        mWebViewClient.nextMessageIsAjaxRequest(new AjaxRequestContents(method, body));
    }

    @JavascriptInterface
    public void customSubmit(String json, String method, String enctype) {
    
    
    	Log.e("zbm", "customSubmit data: " + json + "---encrypt:" + encrypt);
        mWebViewClient.nextMessageIsFormRequest(
                new FormRequestContents(method, json, enctype));
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_40855673/article/details/121575150