zoukankan      html  css  js  c++  java
  • 屏蔽电信流氓广告造成的诡异的问题--Android WebView 长时间不能载入页面

    发如今家里的时候用Android App里的WebView打开站点非常慢,会有十几秒甚至更长时间的卡住。

    可是在电脑上打开相同的网页却非常快。

    查找这个问题的过程比較曲折,记录下来。

    抓取Android网络数据

    为了调试这个问题,首先要抓取Android的网络包数据。開始时,是想用Wireshark来抓包的,可是非常麻烦,tcpdump在手机要root权限。

    于是转换思路,能不能在Android上设置代理,来抓包?

    可是fiddler没有linux版本号,于是转用BurpSuite了。

    设置Android代理方法:

    在Android网络设置里,长按连接,选择“改动网络”,“显示高级选项”,“代理”,“手动”,然后填上相应的代理的地址。

    hosts和路由器配置的坑

    抓取到http请求数据,发现訪问非常快,比在手机上快多了。说明并非网络问题。

    再细致观察,发现了这个请求:

    GET /gngo.js HTTP/1.1
    Host: x.adpro.cn

    回忆起来,这个是曾经屏蔽电信在网页上插入的流氓广告时配置了hosts:

    127.0.0.1 adpro.cn
    127.0.0.1 x.adpro.cn

    于是在电脑上把这两个hosts凝视掉之后,发现速度变慢了一点,可是不会像手机上那样卡十几秒。

    再尝试在电脑上的浏览器打开http://x.adpro.cn/gngo.js,发现打不开。

    ping x.adpro.cn

    发现返回的结果是127.0.0.1

    为什么在hosts文件中把 x.adpro.cn的条目凝视掉了,返回的结果还是127.0.0.1?

    折腾了一阵子,尝试各种清除linux dns的方法,发现x.adpro.cn的解析结果还是127.0.0.1。

    再次想起,曾经在路由器上配置过防火墙,果然例如以下有配置了对adpro.cn的拦截:


    在路由器里把这个规则失效之后,果然ping x.adpro.cn能返回正确的IP了。

    原来是路由器把dns相关的请求也拦截了,导致linux取不到新的dns解析结果,一直用的都是旧的结果,所以总是把x.adpro.cn解析为127.0.0.1。

    搞清楚缘由之后,又一次在路由器里拦截adpro.cn的数据包,然后又一次载入网页,发现http://x.adpro.cn/gngo.js的请求会在十几秒之后超时:


    这就是在手机上为什么打开网页要十几秒的原因了:

    路由器把adpro.cn的数据包拦截了,从而socket全然没有数据返回,所以http请求在十几秒后超时,Android WebView才渲染显示出页面。

    为什么电脑上非常快?由于配置了127.0.0.1 x.adpro.cn,所以http请求直接返回失败了,不会堵塞住。

    很影响体验的运营商广告

    在路由器上把拦截去掉,再在手机上訪问,又出现了一个坑爹的事情:

    在WebWiew上会显示电信插入的流氓广告,把大部分区域都挡住了。



    怎样过滤掉运营商的流氓广告?黑名单还是白名单

    假设只是滤掉的话,用户还以后是站点自己弹的广告。那么怎样在App里过滤掉这些流氓广告?

    在WebView里过滤某些url:

    当url里含有广告地址时,直接返回一个空的回应。

    http://developer.android.com/reference/android/webkit/WebViewClient.html#shouldInterceptRequest(android.webkit.WebView, java.lang.String) http://developer.android.com/reference/android/webkit/WebViewClient.html#shouldInterceptRequest(android.webkit.WebView, java.lang.String)

    		webView.setWebViewClient(new WebViewClient() {
    			public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
    				if (url.contains("adpro.cn")) {
    					return new WebResourceResponse(null, null, null);
    				}
    				return null;
    			}

    注意的是在api level 11上才干够重载上面的函数。

    运营商的广告域名都是相对固定的,能够用黑名单来排除掉。

    当然,假设自己的服务都是在自己的域名下的,那么能够考虑採用白名单机制。

    白名单机制另一个额外的优点,能够算是一个有一定效果的防止XSS的方法了。


    其他的一些东东:

    Android上抓包的一些文章:

    http://www.trinea.cn/android/android-network-sniffer/     Android利用Fiddler进行网络数据抓包 

    http://www.freebuf.com/articles/wireless/6517.html    实时抓取移动设备上的通信包(ADVsock2pipe+Wireshark+nc+tcpdump)


  • 相关阅读:
    图片懒加载
    浅谈javascript的函数节流
    js字符串常用方法详解
    js数组详解
    thinkphp3.2 批量添加数据
    openssl证书及配置
    手机访问PC端
    mui框架(三)
    mui框架(二)
    mui框架(一)
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3954498.html
Copyright © 2011-2022 走看看