1. 程式人生 > 其它 >Android攔截並獲取WebView內部POST請求引數

Android攔截並獲取WebView內部POST請求引數

Android攔截並獲取WebView內部POST請求引數

實現過程

方案一

shouldInterceptRequest中攔截所有請求

webView.setWebViewClient(new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        try {
            URL url = new URL(request.getUrl());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        Log.e("InternetActivity", request + "");
        return super.shouldInterceptRequest(view, request);
    }

});

但是通過此方法只能獲取get請求的引數(因為引數直接拼在了url連結中),對於post請求的引數無可奈何。

方案二

後來參考了request_data_webviewclient,有了新的實現方式,具體原理為:給H5注入一段js程式碼,目的是在每次Ajax請求都會呼叫Android原生的方法,將請求引數傳給客戶端。

js注入程式碼:如下:

<script language="JavaScript">

    function generateRandom() {
      return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
    }


    // This only works if `open` and `send` are called in a synchronous way
    // That is, after calling `open`, there must be no other call to `open` or
    // `send` from another place of the code until the matching `send` is called.
    requestID = null;
    XMLHttpRequest.prototype.reallyOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
        requestID = generateRandom()
        var signed_url = url + "AJAXINTERCEPT" + requestID;
        this.reallyOpen(method, signed_url , async, user, password);
    };
    XMLHttpRequest.prototype.reallySend = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = function(body) {
        interception.customAjax(requestID, body);
        this.reallySend(body);
    };

</script>

客戶端攔截請求:


@Override
public final WebResourceResponse shouldInterceptRequest(final WebView view, WebResourceRequest request) {
    String requestBody = null;
    Uri uri = request.getUrl();

    // 判斷是否為Ajax請求(只要連結中包含AJAXINTERCEPT即是)
    if (isAjaxRequest(request)) {
        // 獲取post請求引數
        requestBody = getRequestBody(request);
        // 獲取原連結
        uri = getOriginalRequestUri(request, MARKER);
    }

    // 重新構造請求,並獲取response
    WebResourceResponse webResourceResponse = shouldInterceptRequest(view, new WriteHandlingWebResourceRequest(request, requestBody, uri));
    if (webResourceResponse == null) {
        return webResourceResponse;
    } else {
        return injectIntercept(webResourceResponse, view.getContext());
    }
}