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请求参数的实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • 详解Android中使用OkHttp发送HTTP的post请求的方法

    HTTP POST 和 PUT 请求可以包含要提交的内容.只需要在创建 Request 对象时,通过 post 和 put 方法来指定要提交的内容即可. HTTP POST 请求的基本示例: public class PostString { public static void main(String[] args) throws IOException { OkHttpClient client = new OkHttpClient(); MediaType MEDIA_TYPE_TEXT

  • Android 实现电话拦截及拦截提示音功能的开发

    本文所讲的内容是在Android系统中如何写程序进行电话拦截,并发出拦截提示音提醒用户,可以说此功能还是比较实用的.        1.电话拦截 这个功能大家可能都知道了,就是利用反射原理调用ITelephony的隐藏方法来实现.        2.拦截后提示忙音/空号/已关机/已停机 这个功能其实是要用到MMI指令,具体如何设置呼叫转移的指定可以参考这里 http://baike.baidu.com/view/206402.html?fromTaglist. 在本文中我们会用到"遇忙转移&qu

  • 详解Android事件的分发、拦截和执行

    在平常的开发中,我们经常会遇到点击,滑动之类的事件.有时候不同的view之间也存在各种滑动冲突.比如布局的内外两层都能滑动的话,那么就会出现冲突了.这个时候我们就需要了解Android的事件分发机制. Android的触摸事件分发过程由三个很重要的方法来共同完成:dispatchTouchEvent.onInterceptTouchEvent.onTouchEvent.我先将这三个方法大体的介绍一下. •public boolean dispatchTouchEvent(MotionEvent

  • Android中Home键的监听和拦截示例

    首先大家应该先了解一种情况,就是Android在应用中是无法拦截Home键的,今天我们带大家看一下Home键的三种情况. 1.在应用中按下Home键的逻辑处理 当我们在应用中按下Home键时界面会启动到桌面,我们在frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.Java类中可以看到其实现原理,其不外乎就是调用了以下代码. Intent mHomeIntent; mHomeIntent =

  • Android客户端post请求服务器端实例

    Android客户端请求服务器端的详细解释 1. Android客户端与服务器端通信方式: Android与服务器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post两种方式. 2. 解析服务器端返回数据的解释: (1).对于服务器端来说,返回给客户端的数据格式一般分为html.xml和json这三种格式. (2). JSON(Javascript Object Notation)是一种轻量级的数据交换格式,相比于xml这种数据交换格式来说,因为解析xml比

  • Android使用httpPost向服务器发送请求的方法

    本文实例讲述了Android使用httpPost向服务器发送请求的方法.分享给大家供大家参考,具体如下: import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http

  • Android开发实现的电话窃听和拦截应用

    本文实例讲述了Android开发实现的电话窃听和拦截应用.分享给大家供大家参考,具体如下: 今天学习了进程间Service的通信-->AIDL,基于前几天学习的广播机制,我做了一个简单的电话窃听和录音应用.现将具体实现方法附在下面,供大家参考,希望大家提供一些宝贵的意见. 业务需求分析: 1.当手机处于开机状态,监听服务就要启动,对来电进行监听录音. 2.设置电话黑名单,当来电是黑名单电话,则直接挂断. 实现步骤: 首先我们要定义一个电话监听的服务,对来电进行监听录音和拦截.具体代码如下: Ph

  • Android项目实现短信的发送、接收和对短信进行拦截

    说实话,关于Android中对短信的一些相关操作是一个比较入门的东西.那我现在还要来写这一篇博客的原因只是因为现在开发中有相关内容,而又想将这些东西分享给更多的人来学习,同时在以后对Android系统的短信进行其他学习的时候也就放在这里做一个记录了,于是就写了这篇啰嗦的文章.如果你觉得这是一个不错的东西,欢迎收藏,以便在以后更方便地查看本人在此篇文章中更新的内容.下面我就从标题中的三个方面来对Android系统中的短信操作进行一个简单地学习. 短信的发送 由于Android中对短信发送方法的优良

  • Android中post请求传递json数据给服务端的实例

    在最近的项目中有个需求是这样的: 入参封装成JSON,EXAMPLE: { "uuid": "iamauuid", "clientType": "AND", "content": "{\"gender\":\"F\",\"name\":\"TTT\"}"} 其中content中是json的object,且要求

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

    起因: 有些时候自家APP中嵌入的H5页面并不是自家的.但是很多时候又想在H5不知情的情况下获取H5内部请求的参数,这应该怎么做到呢? 带着这个疑问,就有了这篇博客. 实现过程: 方案一: 最开始想到的方案是直接拦截H5中所有的请求: webView.setWebViewClient(new WebViewClient() { @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResource

  • Android使用原生组件WebView加载网页和数据的方法

    在Api中关于这个类的介绍大致就是这是一个可以显示网页的视图,如: webView.loadUrl(http://www.baidu.com/); 显示结果: 还可以加载一些html的字符串,如: String str = "<html><body>You scored <b>192</b> points.</body></html>"; webView.loadData(str, "text/html&

  • Android使用GPS获取用户地理位置并监听位置变化的方法

    本文实例讲述了Android使用GPS获取用户地理位置并监听位置变化的方法.分享给大家供大家参考,具体如下: LocationActivity.java /* LocationActivity.java * @author octobershiner * 2011 7 22 * SE.HIT * 一个演示定位用户的位置并且监听位置变化的代码 * */ package uni.location; import android.app.Activity; import android.content

  • java 获取request中的请求参数代码详解

    1.get 和 post请求方式 (1)request.getParameterNames(); 获取所有参数key后.遍历request.getParameter(key)获取value (2)request.getParameterMap() .直接包含参数key和value值,简单方便 Map<String, String[]>maps = request.getParameterMap(); for (Map.Entry<String, String[]> entry :

  • springboot中不能获取post请求参数的解决方法

    问题描述 最近在做微信小程序,用的spring boot做后端,突然发现客户端发送post请求的时候服务端接收不到参数.问题简化之后如下: 微信小程序端: 在页面放一个按钮进行测试 <!--index.wxml--> <view class="container"> <button catchtap='testpost'>点击进行测试</button> </view> 绑定一个函数发送post请求 //index.js //获

  • python+excel接口自动化获取token并作为请求参数进行传参操作

    1.登录接口登录后返回对应token封装: import json import requests from util.operation_json import OperationJson from base.runmethod import RunMethod class OperationHeader: def __init__(self, response): self.response = json.loads(response) def get_response_token(self

  • yii2 在控制器中验证请求参数的使用方法

    写api接口时一般会在控制器中简单验证参数的正确性. 使用yii只带验证器(因为比较熟悉)实现有两种方式(效果都不佳). 针对每个请求单独写个 Model , 定义验证规则并进行验证. 缺点:写好多参数验证的 Model 类. 使用 独立验证器 中提到的 $validator->validateValue() 方法直接验证变量值.缺点:写实例化很多验证器对象. 有么有"一劳永逸"的做法,像在 Model 中通过 rules 方法定义验证规则并实现快速验证的呢?有! 使用方法(实现

  • 使用AOP拦截Controller获取@PathVariable注解传入的参数

    目录 AOP拦截Controller获取@PathVariable注解传入参数 前言: 示例代码: 处理: 扩展: aop中获取request和response 动态参数使用@PathVariable解析 现在有如下的一条超链接 在Controller层的代码如下 AOP拦截Controller获取@PathVariable注解传入参数 前言: 最近项目中需要对controller传入的应用标识(appMarkId)进行校验,appMarkId@PathVariable传入到url模版中的,这里

  • Android开发之获取SD卡及手机ROM容量的方法

    本文实例讲述了Android获取SD卡及手机ROM容量的方法.分享给大家供大家参考,具体如下: 这里通过一个简单的小例子,来获取SD卡的容量和手机ROM的容量,代码如下: package com.urovo.sdcardspace; import java.io.File; import android.os.Bundle; import android.os.Environment; import android.os.StatFs; import android.app.Activity;

  • Android OnCreate()中获取控件高度与宽度两种方法详解

    Android OnCreate()中获取控件高度与宽度 试过在OnCreate()中获取控件高度与宽度的童鞋都知道,getWidth()与getHeight()方法返回是0,具体原因 看一下Activity的生命周期 就会明白. 上代码: 方法一: int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0,View.Me

随机推荐