Android拦截并获取WebView内部POST请求参数
起因:
有些时候自家APP中嵌入的H5页面并不是自家的。但是很多时候又想在H5不知情的情况下获取H5内部请求的参数,这应该怎么做到呢?
带着这个疑问,就有了这篇博客。
实现过程:
方案一:
最开始想到的方案是直接拦截H5中所有的请求:
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());
}
}
客户端注入js代码:
private WebResourceResponse injectIntercept(WebResourceResponse response, Context context) {
String encoding = response.getEncoding();
String mime = response.getMimeType();
// WebResourceResponse的mime必须为"text/html",不能是"text/html; charset=utf-8"
if (mime.contains("text/html")) {
mime = "text/html";
}
InputStream responseData = response.getData();
InputStream injectedResponseData = injectInterceptToStream(
context,
responseData,
mime,
encoding
);
return new WebResourceResponse(mime, encoding, injectedResponseData);
}
注:根据谷歌官方文档,mime必须为"text/html"。

反思:
- 开发过程中遇到了页面一直显示不了的问题,实际上就是因为获取到的mime是"text/html; charset=utf-8",得改成"text/html";
- 通过此方法也可篡改response与request,但不要滥用;
- 所以说,Android确实不安全!
GitHub地址:webview_post_data
大家如果有什么疑问或者建议可以通过评论或者邮件的方式联系我,欢迎大家的评论~
Android拦截并获取WebView内部POST请求参数的更多相关文章
- springboot springmvc拦截器 拦截POST、PUT、DELETE请求参数和响应数据,并记录操作日志
1.操作日志实体类 @Document(collection = "operation_log") @Getter @Setter @ToString public class O ...
- java从request中获取GET和POST请求参数
URL和参数列表 一 获取请求方式 request.getMethod(); get和post都可用, 二 获取请求类型 request.getContentType(); get和post都可用,示 ...
- requset获取post提交的请求参数
1.请求体的内容通常是通过post来提交的,格式是 username=zhansan&password=123&hobby=football||&hobby=basketbal ...
- java 获取request中的请求参数
1.get 和 post请求方式 (1)request.getParameterNames(); 获取所有参数key后.遍历request.getParameter(key)获取value (2)re ...
- SpringBoot 拦截器获取http请求参数
SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 目录 SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 获取http请求参数是一种刚需 定义拦截器获取请求 为 ...
- jmeter脚本中请求参数获取的几种方式
a.从数据库获取: 譬如接口请求参数中id的值,我需要从数据库获取,如下设置: 先设置jdbc connection configuration,然后设置JDBC b.从CSV获取: 获取CSV文件 ...
- struts2视频学习笔记 11-12(动态方法调用,接收请求参数)
课时11 动态方法调用 如果Action中存在多个方法时,可以使用!+方法名调用指定方法.(不推荐使用) public String execute(){ setMsg("execute&q ...
- Android之网络----使用HttpClient发送HTTP请求(通过get方法获取数据)
[正文] 一.HTTP协议初探: HTTP(Hypertext Transfer Protocol)中文 "超文本传输协议",是一种为分布式,合作式,多媒体信息系统服务,面向应用层 ...
- [Android] 获取WebView的页面标题(Title)-----WebChromeClient.onReceivedTitle()方法的重写
应用开发中需要获取WebView当前页面的标题,可能通过对WebChromeClient.onReceivedTitle()方法的重写来实现 效果图如下: 代码如下: public class Mai ...
随机推荐
- thymeleaf 货币格式化 数字格式化问题
格式化数字对象 ${'¥'+#numbers.formatDecimal(pro.price,0,'COMMA',2,'POINT')} ${'¥'+#numbers.formatDecimal(pr ...
- maven工程,java代码加载resources下面资源文件的路径
1 通过类加载器加载器, 1. URL resource = TestMain.class.getResource("/18500228040.txt");File file = ...
- AXIS2整合spring需要的jar,以及大部分缺少jar所报的异常
axis2 webservice 服务端jar包: -->axis2-kernel-1.6.1.jar -->axis2-spri ...
- MySQL松散索引扫描与紧凑索引扫描
什么是松散索引? 答:实际上就是当MySQL 完全利用索引扫描来实现GROUP BY 的时候,并不需要扫描所有满足条件的索引键即可完成操作得出结果. 要利用到松散索引扫描实现GROUP BY,需要至少 ...
- PAT1017:Queueing at Bank
1017. Queueing at Bank (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Supp ...
- SpringMVC中参数绑定
SpringMVC中请求参数的接收主要有两种方式, 一种是基于HttpServletRequest对象获取, 另外一种是通过Controller中的形参获取 一 通过HttpServletReque ...
- 【手记】解决EXCEL跑SQL遇“查询无法运行或数据库表无法打开...”
报错: 解决:在语句开头指定SET NOCOUNT ON 就是这么神cao奇dan. -END-
- 为何没有asia/beijing时区?
Asia/Beijing 这个时区是消失了么? 大约1小时 ago @tinyfool 对啊,我就奇怪为什么北京时间就要用上海和成都... 大约1小时 ago @tinyfool @CatChen我所 ...
- CMD命令锦集
虽然随着计算机产业的发展,Windows 操作系统的应用越来越广泛,DOS 面临着被淘汰的命运,但是因为它运行安全.稳定,有的用户还在使用,所以一般Windows 的各种版本都与其兼容,用户可以在Wi ...
- 你不知道的JavaScript--Item12 undefined 与 null
当讨论JavaScript中的原始数据类型时,大多数人都知道从String.Number到Boolean的基本知识.这些原始类型相当简单,行为符合常识.但是,本文将更多关注独特的原始数据类型Null和 ...