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