需求背景

接到这样一个需求,需要在 WebView 的所有网络请求中,在请求的url中,加上一个sign=xxxx 的标志位,同时添加手机本地的数据比如 sessionToken=sd54f5sd4ffsdf45454564  、deviceId=863970025919887



后端主要函数

如下是http://192.168.1.52/web/post.html的html数据,由于是局域网链接,大家连不上

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><meta http-equiv="Content-type" content="text/html; charset=utf-8"></head><script src="jquery-2.1.4.min.js"></script><script>
/**
sign:"1bb6b8e28acb46e2801d352e0fb59b6e"
**//**
$.getJSON("http://192.168.1.52/gateway/testBindBankCard?sessionToken=abfda&userId=12&bankname=中国银行&branchBank=中国>银>行北京分行&bankCode=24839&bankCardNo=63238941329210832819&shortMsgCode=23&cardOwner=王腾飞" ,function(data){if(data.errcode=='0'){$("#g1").text("恭喜你GET成功了!");}else$("#g1").text(data.errmsg);});
**/
$.getJSON("http://192.168.1.52/gateway/testBindBankCard?bankCardNo=63238941329210832819&bankCode=4839&bankname=中国银行&branchBank=中银行北京分行&cardOwner=王腾飞&shortMsgCode=23&userId=12" ,function(data){if(data.errcode=='0'){$("#g1").text("恭喜你GET成功了!");}else$("#g1").text(data.errmsg);});$.ajax({type: 'POST',url: "http://192.168.1.52/gateway/testBindBankCard" ,data: {
userId:"12",
bankname:"中国银行",
branchBank:"中银行北京分行",
bankCode:"4839",
bankCardNo:"63238941329210832819",
shortMsgCode:"23",
cardOwner:"王腾飞"
},success: function function_name (data) {if(data.errcode=='0'){$("#div").text("恭喜你POST成功了!");}else$("#div").text(data.errmsg);}});</script><body><h1>测试页面</h1>本次测试结果为:<div id="div" style="font-size:28px;color:red;"></div><div id="g1" style="font-size:28px;color:red;"><div></body>
</html>

html中是aiax中的post请求如下:

$.ajax({type: 'POST',url: "http://192.168.1.52/gateway/testBindBankCard" ,data: {
userId:"12",
bankname:"中国银行",
branchBank:"中银行北京分行",
bankCode:"4839",
bankCardNo:"63238941329210832819",
shortMsgCode:"23",
cardOwner:"王腾飞",
sessionToken:"43248329"
}

html中 data中的数据是post请求的body体,我需要将该链接中body体进行拦截并加上自带标志和参数
"&deviceId="+MyApplication.device_id+"&sessionToken="+"43248329"+"&sign="+sign

http://192.168.1.52/gateway/testBindBankCard?userId=12&bankname=中国银行&branchBank=中银行北京分行&bankCode=4839&bankCardNo=6323894132921089&shortMsgCode=23&cardOwner=王腾飞&deviceId=863970025919887&sessionToken=43248329&sign=fc806225b90b38ee9d7394870afc2b4f

//get请求 需求类似

Android主要函数

InterceptingWebViewClient.Java重写WebViewClient类,进行相应的url拦截、回调

package com.cloudhome.webview_intercept;import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;import com.squareup.mimecraft.FormEncoding;import org.json.JSONArray;
import org.json.JSONObject;import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;import okhttp3.OkHttpClient;public class InterceptingWebViewClient extends WebViewClient {public static final String TAG = "InterceptingWebViewClient";private Context mContext = null;private WebView mWebView = null;private PostInterceptJavascriptInterface mJSSubmitIntercept = null;private OkHttpClient client = new OkHttpClient();public InterceptingWebViewClient(Context context, WebView webView) {mContext = context;mWebView = webView;mJSSubmitIntercept = new PostInterceptJavascriptInterface(this);mWebView.addJavascriptInterface(mJSSubmitIntercept, "interception");}//    @Override
//    public void onPageStarted(WebView view, String url, Bitmap favicon){
//        if (url.startsWith("https://")) { //NON-NLS
//
//            mNextAjaxRequestContents = null;
//            mNextFormRequestContents = null;
//            view.stopLoading();
//            // DO SOMETHING
//        }
//    }@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {mNextAjaxRequestContents = null;mNextFormRequestContents = null;view.loadUrl(url);return true;}
//    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
//    @Override
//    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
//        if (request != null && request.getUrl() != null) {
//
//            String scheme = request.getUrl().getScheme().trim();
//            if (scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https")) {
//                URL url;
//                URLConnection connection;
//                HttpURLConnection conn ;
//
//                try {
//                    if (request.getMethod().equals("POST")) {
//                         url= new URL(request.getUrl().toString());
//                         connection = url.openConnection();
//                        conn = (HttpURLConnection) connection;
//                        Log.d("7777776",request.getUrl().toString());
//                        conn.setRequestMethod( "POST");
//                        OutputStream os = conn.getOutputStream();
//                        if (mNextAjaxRequestContents != null) {
//
//                            Log.d("777777","44444");
//                            writeBody(os);
//                        } else {
//
//                            Log.d("777777","5555");
//                            writeForm(os);
//                        }
//                        os.close();
//
//
//
//                        // Read input
//                        String charset = conn.getContentEncoding() != null ? conn.getContentEncoding() : Charset.defaultCharset().displayName();
//                        String mime = conn.getContentType();
//                        byte[] pageContents = IOUtils.readFully(connection.getInputStream());
//
//                        // Perform JS injection
//                        if (mime.equals("text/html")) {
//                            pageContents = PostInterceptJavascriptInterface
//                                    .enableIntercept(mContext, pageContents)
//                                    .getBytes(charset);
//                        }
//
//                        // Convert the contents and return
//                        InputStream isContents = new ByteArrayInputStream(pageContents);
//
//                        return new WebResourceResponse(mime, charset,
//                                isContents);
//
//
//                    }else{
//                         url = new URL(injectIsParams(request.getUrl().toString()));
//                        connection = url.openConnection();
//                        Log.d("7777779",request.getUrl().toString());
//                    }
//
//
//
//
//
//                    // Write body
//                    if (request.getMethod().equals("GET")) {
//
//                        String contentType = connection.getContentType();
//                        // If got a contentType header
//                        if(contentType != null) {
//
//                            String mimeType = contentType;
//
//                            // Parse mime type from contenttype string
//                            if (contentType.contains(";")) {
//                                mimeType = contentType.split(";")[0].trim();
//                            }
//
//
//                            return new WebResourceResponse(mimeType, connection.getContentEncoding(), connection.getInputStream());
//                        }
//
//                    }
//
//
//
//
//                } catch (MalformedURLException e) {
//                    e.printStackTrace();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        return null;
//    }@Overridepublic WebResourceResponse shouldInterceptRequest(final WebView view, final String urlstr) {try {// Our implementation just parses the response and visualizes it. It does not properly handle// redirects or HTTP errors at the moment. It only serves as a demo for intercepting POST requests// as a starting point for supporting multiple types of HTTP requests in a full fletched browserURL url = null;if (isPOST()) {url = new URL(urlstr);Log.d("77777post",urlstr);} else {Log.d("77777get", urlstr);url = new URL(injectIsParams(urlstr));}Log.d("77777get",url.toString());URLConnection rulConnection = url.openConnection();HttpURLConnection conn = (HttpURLConnection) rulConnection;conn.setRequestProperty("Accept-Charset", "utf-8");conn.setRequestProperty("contentType", "utf-8");conn.setRequestMethod(isPOST() ? "POST" : "GET");// Write bodyif (isPOST()) {OutputStream os = conn.getOutputStream();if (mNextAjaxRequestContents != null) {writeBody(os);} else {writeForm(os);}os.close();}//           else{
//                String contentType = rulConnection.getContentType();
//                // If got a contentType header
//                if(contentType != null) {
//
//                    String mimeType = contentType;
//
//                    // Parse mime type from contenttype string
//                    if (contentType.contains(";")) {
//                        mimeType = contentType.split(";")[0].trim();
//                    }
//
//
//                    return new WebResourceResponse(mimeType, rulConnection.getContentEncoding(), rulConnection.getInputStream());
//                }
//
//            }// Read inputString charset = conn.getContentEncoding() != null ? conn.getContentEncoding() : Charset.defaultCharset().displayName();String mime = conn.getContentType();byte[] pageContents = IOUtils.InputStreamTOByte(conn.getInputStream());// Perform JS injectionif (mime.equals("text/html")) {pageContents = PostInterceptJavascriptInterface.enableIntercept(mContext, pageContents).getBytes(charset);}Log.d("888888",charset);// Convert the contents and returnInputStream isContents = new ByteArrayInputStream(pageContents);mNextAjaxRequestContents=null;return new WebResourceResponse(mime, charset,isContents);} catch (FileNotFoundException e) {Log.w("Error 404","Error 404:" + e.getMessage());e.printStackTrace();return null;        // Let Android try handling things itself} catch (Exception e) {e.printStackTrace();return null;        // Let Android try handling things itself}}private boolean isPOST() {return (mNextAjaxRequestContents!=null&&mNextAjaxRequestContents.method.equals("POST"));}private void writeBody(OutputStream out) {try {Log.d("777773", mNextAjaxRequestContents.body);out.write(mNextAjaxRequestContents.body.getBytes("UTF-8"));} catch (IOException e) {throw new RuntimeException(e);}}protected void writeForm(OutputStream out) {try {JSONArray jsonPars = new JSONArray(mNextFormRequestContents.json);// We assume to be dealing with a very simple form here, so no file uploads or anything// are possible for reasons of clarityFormEncoding.Builder m = new FormEncoding.Builder();for (int i = 0; i < jsonPars.length(); i++) {JSONObject jsonPar = jsonPars.getJSONObject(i);m.add(jsonPar.getString("name"), jsonPar.getString("value"));// jsonPar.getString("type");// TODO TYPE?}m.build().writeBodyTo(out);} catch (Exception e) {throw new RuntimeException(e);}}public String getType(Uri uri) {String contentResolverUri = mContext.getContentResolver().getType(uri);if (contentResolverUri == null) {contentResolverUri = "*/*";}return contentResolverUri;}private PostInterceptJavascriptInterface.FormRequestContents mNextFormRequestContents = null;public void nextMessageIsFormRequest(PostInterceptJavascriptInterface.FormRequestContents formRequestContents) {mNextFormRequestContents = formRequestContents;}private PostInterceptJavascriptInterface.AjaxRequestContents mNextAjaxRequestContents = null;public void nextMessageIsAjaxRequest(PostInterceptJavascriptInterface.AjaxRequestContents ajaxRequestContents) {mNextAjaxRequestContents= ajaxRequestContents;}/*** 当GET请求时,修改url的函数位置*/public static String injectIsParams(String url) throws UnsupportedEncodingException {//此处省略拼接函数......}}

PostInterceptJavascriptInterface.Java 用来识别url请求是GET请求还是POST请求

package com.cloudhome.webview_intercept;import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.webkit.JavascriptInterface;import org.jsoup.Jsoup;import java.io.IOException;
import java.io.UnsupportedEncodingException;public class PostInterceptJavascriptInterface {public static final String TAG = "PostInterceptJavascriptInterface";private static String mInterceptHeader = null;private InterceptingWebViewClient mWebViewClient = null;public PostInterceptJavascriptInterface(InterceptingWebViewClient webViewClient) {mWebViewClient = webViewClient;}public static String enableIntercept(Context context, byte[] data) throws IOException {if (mInterceptHeader == null) {mInterceptHeader = new String(IOUtils.InputStreamTOByte(context.getAssets().open("www/interceptheader.html")), "utf-8");}Log.d("4444", data.toString());org.jsoup.nodes.Document doc = Jsoup.parse(new String(data, "utf-8"));doc.outputSettings().prettyPrint(true);// Prefix every script to capture submits// Make sure our interception is the first element in the// headerorg.jsoup.select.Elements el = doc.getElementsByTag("head");if (el.size() > 0) {el.get(0).prepend(mInterceptHeader);}String pageContents = doc.toString();Log.d("777777", pageContents);return pageContents;}/*** 当POST请求时,修改url的函数位置*/public static String injectIsParams(String url) throws UnsupportedEncodingException {//此处省略拼接函数......return urlEncode;}@JavascriptInterfacepublic void customAjax(final String method, final String body) throws UnsupportedEncodingException {Log.i(TAG, "Submit data: " + method + " " + body);//  Log.i("77777",url);// injectIsParams(body);mWebViewClient.nextMessageIsAjaxRequest(new AjaxRequestContents(method, injectIsParams(body + "")));}@TargetApi(Build.VERSION_CODES.LOLLIPOP)@JavascriptInterfacepublic void customSubmit(String json, String method, String enctype) {Log.i(TAG, "Submit data: " + json + "\t" + method + "\t" + enctype);mWebViewClient.nextMessageIsFormRequest(new FormRequestContents(method, json, enctype));}public class FormRequestContents {public String method = null;public String json = null;public String enctype = null;public FormRequestContents(String method, String json, String enctype) {this.method = method;this.json = json;this.enctype = enctype;}}public class AjaxRequestContents {public String method = null;public String body = null;public AjaxRequestContents(String method, String body) {this.method = method;this.body = body;}}}




在android assets / www文件夹中 添加interceptheader.html 获取url请求header和body等参数

<script language="JavaScript">HTMLFormElement.prototype._submit = HTMLFormElement.prototype.submit;HTMLFormElement.prototype.submit = interceptor;window.addEventListener('submit', function(e) {interceptor(e);}, true);function interceptor(e) {var frm = e ? e.target : this;interceptor_onsubmit(frm);frm._submit();}function interceptor_onsubmit(f) {var jsonArr = [];for (i = 0; i < f.elements.length; i++) {var parName = f.elements[i].name;var parValue = f.elements[i].value;var parType = f.elements[i].type;jsonArr.push({name : parName,value : parValue,type : parType});}interception.customSubmit(JSON.stringify(jsonArr),f.attributes['method'] === undefined ? null: f.attributes['method'].nodeValue,f.attributes['enctype'] === undefined ? null: f.attributes['enctype'].nodeValue);}lastXmlhttpRequestPrototypeMethod = null;XMLHttpRequest.prototype.reallyOpen = XMLHttpRequest.prototype.open;XMLHttpRequest.prototype.open = function(method, url, async, user, password) {lastXmlhttpRequestPrototypeMethod = method;this.reallyOpen(method, url, async, user, password);};XMLHttpRequest.prototype.reallySend = XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send = function(body) {interception.customAjax(lastXmlhttpRequestPrototypeMethod, body);lastXmlhttpRequestPrototypeMethod = null;this.reallySend(body);};
</script>

webview 请求访问前

webview 请求访问后

注意:恭喜你GET成功了!恭喜你POST成功了!不是webview直接访问得到的结果,而是拦截webview访问中另外两个网络请求,拼接自带的参数通过后台验证得到的结果。

我的demo下载

参考资料

http://www.tuicool.com/articles/VFzY3y3

https://github.com/KeejOow/android-post-webview

感谢@zhangyong125的帮助。



Android中WebView中拦截所有请求并替换URL(支持AJAX的post请求类型)相关推荐

  1. Android开发-WebView中实现Android调用JS JS调用Android 【三】

    老早之前就想总结下Webview相关的知识点了,因为互联网大潮中,很多APP都会使用到Webview,像那些不计其数的电商APP,无一例外的使用Webview:或者一些非电商APP中的像广告页面,注册 ...

  2. Android 在WebView中获取网页源码

    原文链接:http://www.cnblogs.com/hibraincol/archive/2011/10/26/2224866.html 1. 使能javascript: 1 webView.ge ...

  3. android webview 加载本地pdf,android – 在WebView中打开PDF

    我想在我的WebView中打开一个PDF,我在这个论坛上找到并组合了代码. 但是,虽然我安装了多个PDF应用程序,包括Adobe Reader,但它仍然可以找到"找不到PDF应用程序&quo ...

  4. Android在WebView中给图片设置点击事件

    好久没有更新博客了,今天来个小知识点.我们知道在WebView中加载的是Html也面,在开发中都是Web前端人员写好以后给个链接我们去用webView进行loadUrl.但是有时突然产品想让你把加载回 ...

  5. Android—在WebView中下载Blob协议文件

    之前有个需求是要下载Blob协议的gif,让我苦恼了好久.平时下载http协议的文件时直接获取输入流即可,但是Java无法获得Blob协议的文件流,无法直接处理.不过JavaScript处理Blob协 ...

  6. 微信小程序中WebView中原生组件限制问题解析

    背景 在微信的文档中有一个章节说明了『 原生组件的使用限制 』有这么一段话 『由于原生组件脱离在 WebView 渲染流程外,因此在使用时有以下限制:原生组件的层级是最高的,所以页面中的其他组件无论设 ...

  7. http模块中----------req请求对象-req.url req.method 与客户端请求相关

    服务器收到客户端发送的请求,就会调用通过server.on() 为服务器绑定request事件处理函数 //监听客户端的请求 server.on('request',(req,res)=>{   ...

  8. ajax+php跨域请求数据库,基于jQuery的ajax跨域请求,PHP作为服务器端代码

    ajax实现跨域请求有两种方式: 方法一:jsonp的方式 jsonp方式的关键点在客户请求以jsonp作为数据类型,服务器端接收jsonp的回调函数,并通过回调函数进行数据的传输.具体代码如下: 客 ...

  9. 在android的webview中跳转到微信支付和支付宝app支付

    @Override public boolean shouldOverrideUrlLoading(WebView view, String url) {// 如下方案可在非微信内部WebView的H ...

最新文章

  1. Node:非IO的异步API
  2. C++ Double-Ended Queues(双向队列)
  3. 深度学习训练中关于数据处理方式--原始样本采集以及数据增广
  4. BZOJ2240 : ural1676 Mortal Combat
  5. 【kafka】kafka 判断消费组死掉方案 group dead
  6. wifi管家android,WiFi管家—轻松连上好wifi
  7. 360服务器被劫持怎么修复,360浏览器网络劫持导致主页被改怎么办?360浏览器网络劫持导致主页被改的解决办法...
  8. 毕向东_Java基础
  9. 公园智慧路灯解决方案
  10. ArcGIS Server 切片数学关系阐释,小区域切图频繁出错解决方法
  11. 聚播群控微信二次开发sdk完整API
  12. 北京五险一金介绍及公积金领取办法
  13. 使用匿名函数求三个数的最大值
  14. 如何使用VisiPic消除重复的照片
  15. Python入门(廖雪峰老师)
  16. 我的Mysql 使用小册
  17. 微机 微型计算机,微型计算机杂志
  18. 控制两个div不换行
  19. [LOJ 6035] 洗衣服
  20. 排列组合之——全组合(c语言)

热门文章

  1. python将子进程的输出抛向黑洞
  2. 小米刷机救砖包 最全资料和简单易学教程下载
  3. 两小时快速搭建微人大成绩单监测系统
  4. 特朗普:美国尚未与中国就中兴事宜达成任何协议
  5. 推荐游戏 - Ballance
  6. 如何安装java以及配置环境变量
  7. FPGA verilog 基于SPI总线协议控制flash的项目升级
  8. STM32操作访问flash,包括写入数据到flash和从flash读取数据
  9. 解读西门子的工业软件帝国,巨头的数字化工业战略
  10. 蒙特卡洛路径跟踪 C++实现 图形学冬学期作业