起因:

有些时候自家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请求参数的更多相关文章

  1. springboot springmvc拦截器 拦截POST、PUT、DELETE请求参数和响应数据,并记录操作日志

    1.操作日志实体类 @Document(collection = "operation_log") @Getter @Setter @ToString public class O ...

  2. java从request中获取GET和POST请求参数

    URL和参数列表 一 获取请求方式 request.getMethod(); get和post都可用, 二 获取请求类型 request.getContentType(); get和post都可用,示 ...

  3. requset获取post提交的请求参数

    1.请求体的内容通常是通过post来提交的,格式是 username=zhansan&password=123&hobby=football||&hobby=basketbal ...

  4. java 获取request中的请求参数

    1.get 和 post请求方式 (1)request.getParameterNames(); 获取所有参数key后.遍历request.getParameter(key)获取value (2)re ...

  5. SpringBoot 拦截器获取http请求参数

    SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 目录 SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 获取http请求参数是一种刚需 定义拦截器获取请求 为 ...

  6. jmeter脚本中请求参数获取的几种方式

     a.从数据库获取: 譬如接口请求参数中id的值,我需要从数据库获取,如下设置: 先设置jdbc connection configuration,然后设置JDBC b.从CSV获取: 获取CSV文件 ...

  7. struts2视频学习笔记 11-12(动态方法调用,接收请求参数)

    课时11 动态方法调用 如果Action中存在多个方法时,可以使用!+方法名调用指定方法.(不推荐使用) public String execute(){ setMsg("execute&q ...

  8. Android之网络----使用HttpClient发送HTTP请求(通过get方法获取数据)

    [正文] 一.HTTP协议初探: HTTP(Hypertext Transfer Protocol)中文 "超文本传输协议",是一种为分布式,合作式,多媒体信息系统服务,面向应用层 ...

  9. [Android] 获取WebView的页面标题(Title)-----WebChromeClient.onReceivedTitle()方法的重写

    应用开发中需要获取WebView当前页面的标题,可能通过对WebChromeClient.onReceivedTitle()方法的重写来实现 效果图如下: 代码如下: public class Mai ...

随机推荐

  1. React从入门到放弃之前奏(1):webpack4简介

    接触webpack是好久之前的事情了,最近看了下webpack没想到都到4了. webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler). 会创建1个 ...

  2. JAVA学习资源分享

    JAVA学习资源分享 最高端的JAVA架构师资源(来自龙果学院 价值¥1399元).JAVA互联网分布式架构(龙果学院 价值¥899元).Spring Boot(2017年最新 包括源码原理分析) + ...

  3. PAT1088:Rational Arithmetic

    1088. Rational Arithmetic (20) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue F ...

  4. 构建基于Netty 的HTTP/HTTPS 应用程序

    HTTP/HTTPS是最常见的协议套件之一,并且随着智能手机的成功,它的应用也日益广泛,因为对于任何公司来说,拥有一个可以被移动设备访问的网站几乎是必须的.这些协议也被用于其他方面.许多组织导出的用于 ...

  5. linux 获取网络状态信息(Rtnetlink)

    一.Rtnetlink Rtnetlink 允许对内核路由表进行读和更改,它用于内核与各个子系统之间(路由子系统.IP地址.链接参数等)的通信, 用户空间可以通过NET_LINK_ROUTER soc ...

  6. linux模块驱动之led(ioremap)

    一:led内核驱动 (1)在编写led内核驱动时,我们首先要进行内核裁剪,因为友善之臂将LED灯的驱动默认加载到内核中,所以编写模块驱动程序前就要先把原先的LED灯驱动裁剪掉: led驱动在源码里面的 ...

  7. 【转】java中equal与==的区别 其中有个缓冲区,需要注意

    转自http://www.cnblogs.com/dolphin0520/p/3592500.html 在学Java时,可能会经常碰到下面的代码: 1 String str1 = new String ...

  8. 论文阅读 | CrystalBall: A Visual Analytic System for Future Event Discovery and Analysis from Social Media Data

    CrystalBall: A Visual Analytic System for Future Event Discovery and Analysis from Social Media Data ...

  9. 常用的HTML富文本编译器UEditor、CKEditor、TinyMCE、HTMLArea、eWebEditor、KindEditor简介

    1.UEditor UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于BSD协议,允许自由使用和修改代码... 主要特点: 轻量级: ...

  10. 《javascript语言精粹》读书笔记 Item1 精华与语法

    第一章 精华 任何语言都有其精华的部分和鸡肋的部分,javascript也不例外,而且鸡肋的部分还很多.但javascript的流行却不受他的质量影响. javascript为何如此流行?因为他是we ...