服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android拦截并获取WebView内部POST请求参数的实现方法

Android拦截并获取WebView内部POST请求参数的实现方法

2022-10-13 14:46懒星人 Android

这篇文章主要介绍了Android拦截并获取WebView内部POST请求参数 的实现方法,本文通过两种方案给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

起因:

有些时候自家app中嵌入的h5页面并不是自家的。但是很多时候又想在h5不知情的情况下获取h5内部请求的参数,这应该怎么做到呢?

带着这个疑问,就有了这篇博客。

实现过程:

方案一:

最开始想到的方案是直接拦截h5中所有的请求:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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原生的方法,将请求参数传给客户端。

具体流程如下:

 Android拦截并获取WebView内部POST请求参数的实现方法

其中,

js注入代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<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>

客户端拦截请求:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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"。

Android拦截并获取WebView内部POST请求参数的实现方法

反思:

•开发过程中遇到了页面一直显示不了的问题,实际上就是因为获取到的mime是"text/html; charset=utf-8",得改成"text/html";

•通过此方法也可篡改response与request,但不要滥用;

•所以说,android确实不安全!

github地址:webview_post_data

总结

以上所述是小编给大家介绍的Android拦截并获取WebView内部POST请求参数的实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

原文链接:https://www.cnblogs.com/lanxingren/archive/2019/04/12/10697106.html

延伸 · 阅读

精彩推荐