【问题标题】:Stop Android WebView from trying to load/capture resources like CSS on loadData()阻止 Android WebView 在 loadData() 上尝试加载/捕获 CSS 等资源
【发布时间】:2016-12-01 23:57:14
【问题描述】:

背景

这似乎与许多其他问题重复。相信我,事实并非如此。

我正在尝试将 html 数据加载到 WebView 中,以便能够捕获用户超链接请求。在此过程中,我发现 this answer 完全符合我的要求,除了它捕获对 CSS 文件和图像之类的其他请求:

// you tell the webclient you want to catch when a url is about to load
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request){
    return true;
}
// here you execute an action when the URL you want is about to load
@Override
public void onLoadResource(WebView view, String url){
    if( url.equals("http://cnn.com") ){
        // do whatever you want
    }
}

我已关闭自动图像加载、网络加载和 Javascript 执行:

settings.setBlockNetworkLoads(true);
settings.setBlockNetworkImage(true);
settings.setJavaScriptEnabled(false);

但是这些对于阻止捕获这些请求没有任何作用。

也许有一个不同的过程来捕获链接点击,但要么是这样,要么是为了停止加载外部资源。

问题

如何防止WebView 捕获(或尝试加载)资源请求,例如 CSS、JS 或图像?

否则,如果我无法阻止捕获或尝试加载,我如何区分点击的链接和网络资源?

先谢谢了!

【问题讨论】:

    标签: javascript android html css webview


    【解决方案1】:

    我找到了一种忽略自动 WebView 资源请求的方法。

    通过在 WebView 初始化的第一秒忽略请求,我能够将基于用户的点击与其他点击隔离开来:

    final Long time = System.currentTimeMillis()/1000;
    
    //load up a WebView, define a WebViewClient for capturing link clicking
    WebView webview = new WebView(this);
    WebViewClient webviewClient = new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request){
            return true;
        }
    
        @Override
        public void onLoadResource(WebView view, String url){
            Long currentTime = System.currentTimeMillis()/1000;
            if (currentTime - time > 1) {
                //do stuff here
            }
        }
    };
    

    我没有在不阻止 JavaScript 执行和自动图像加载的情况下测试此解决方案,但无论如何它应该可以工作:

    WebSettings settings = webview.getSettings();
    settings.setBlockNetworkLoads(true);
    settings.setBlockNetworkImage(true);
    settings.setJavaScriptEnabled(false);
    

    【讨论】:

      【解决方案2】:

      您可以覆盖 WebViewClient 的 shouldInterceptRequest 并返回一些非空响应,而不是获取 CSS、JS、图像等。

      例子:

          @Override
          public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
              Log.d(TAG, "shouldInterceptRequest: " + url);
      
              if (url.contains(".css")
                      || url.contains(".js")
                      || url.contains(".ico")) { // add other specific resources..
                  return new WebResourceResponse(
                          "text/css",
                          "UTF-8",
                          getActivity().getResources().openRawResource(R.raw.some_css));
              } else {
                  return super.shouldInterceptRequest(view, url);
              }
          }
      

      R.raw.some_css 在哪里:

          body {
            font-family: sans-serif;
          }
      

      注意:
      我不确定您正在加载哪些页面,但这种方法可能会破坏页面的外观。

      【讨论】:

      • 感谢您的回答!我并不是真的想改变甚至保留页面的 CSS。我正在寻找的是能够捕获在 WebView 中单击的链接,而无需捕获它获取外部资源的尝试。
      【解决方案3】:

      简短的回答是,你不能。

      更长的答案可能是这样的:您将无法这样做,因为它被设计为“捕获全部或不捕获任何内容”。 Web 请求是一个通用概念,与图像或 css 等特定资源无关 - 事实上,它不知道具体是什么。这就是为什么你什么也找不到。

      这样做:在shouldOverrideUrlLoading 中,您不会一直返回true,而是只为您要自己处理的网址返回true。对于所有其他情况,如 css 等,您返回 false,因此 webview 将为您处理这些问题。

      例如:

      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String  url) {
          // Ignore css and js
          if (url.endsWith(".css") || url.endsWith(".js")) {
              return false;
          }
      
          return true;
      }
      

      【讨论】:

      • 感谢您的回答。有什么方法可以区分用户点击的链接和资源加载?
      • 不是我所知道的。当然,您可以做出一些假设,例如“如果它不以 .css、.js、.jpg .png.gif 等结尾,则必须是常规链接”。但这很弱并且可能导致误报,如果该页面具有您未映射的资源。如果您可以控制网页,则可以随时插入一些魔术字符串并查找它。
      • 你的解决方案不就是这样吗?
      • 是的,但就像我在上一条评论中所说,如果您忘记映射某些扩展名(例如,“.webm”文件),您的代码将“认为”这是用户点击链接。但是,我不知道有其他方法可以做到这一点。
      • 实际上,我找到了一种不需要阻止某些资源请求的替代解决方案......如果您有兴趣,请在此处发布。这是我接受的答案。
      猜你喜欢
      • 2017-07-16
      • 1970-01-01
      • 2011-06-18
      • 1970-01-01
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多