Android攔截並獲取WebView內部POST請求引數
阿新 • • 發佈:2021-12-10
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()); } }