Disable Android WebView/WebViewClient Initiated favicon.ico Request

后端 未结 5 843
独厮守ぢ
独厮守ぢ 2021-01-11 16:27

How can I disable the Android WebView/WebViewClient from sending out a request for favicon.ico when I call WebView.loadUrl()? I can see the call being made while profiling r

相关标签:
5条回答
  • 2021-01-11 17:06

    You can simply pass some dummy InputStream to WebResourceResponse as shown below.

    my_webview.webViewClient = object : WebViewClient() {
        override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
            if (request?.url?.toString()?.toLowerCase()?.endsWith("/favicon.ico") == true) {
                val inputStream = "".byteInputStream(Charset.defaultCharset())
                return WebResourceResponse("text", "UTF-8", inputStream)
            } else {
                return super.shouldInterceptRequest(view, request)
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-11 17:08

    This is an answer for Kotlin

    override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
        return if (request?.url?.lastPathSegment == "favicon.ico") {
            WebResourceResponse("image/png", null, null)
        } else {
            super.shouldInterceptRequest(view, request)
        }
    }
    

    By default, return type is not nullable WebResourceResponse when Android Studio generates code, but It does not work so change return type to nullable WebResourceResponse.

    0 讨论(0)
  • 2021-01-11 17:16

    I achieved this by a little hack. First, I've created a fake 1x1 icon file and saved it to the assets folder. Then I overrode WebViewClient's shouldInterceptRequest() method, where I check the URL whether it is the request for favicon file and in that case return WebResourceResponse with InputStream which contains our fake icon:

        @Override
        @CallSuper
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            if(!request.isForMainFrame() && request.getUrl().getPath().equals("/favicon.ico")) {
                try {
                    return new WebResourceResponse("image/png", null, new BufferedInputStream(view.getContext().getAssets().open("empty_favicon.ico")));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    

    Note that the InputStream must not be closed in our code, because it is subsequently used by the WebView to read the icon. The WebviewClient must be set to the WebView via its setter:

    mWebView.setWebViewClient(subclassedWebViewClient);
    
    0 讨论(0)
  • 2021-01-11 17:22

    There is a method for WebView class named getFavicon(). I think that method is called by WebView to retrieve the favicon from server by issuing request. So you can try extending the WebView class and override the getFavicon() method to do nothing. I haven't tried it myself but this might work.

    0 讨论(0)
  • 2021-01-11 17:30

    for me the complete solution was:

       @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
    
            if(url.toLowerCase().contains("/favicon.ico")) {
                try {
                    return new WebResourceResponse("image/png", null, null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            return null;
        }
    
        @Override
        @SuppressLint("NewApi")
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
    
            if(!request.isForMainFrame() && request.getUrl().getPath().endsWith("/favicon.ico")) {
                try {
                    return new WebResourceResponse("image/png", null, null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            return null;
        }
    
    0 讨论(0)
提交回复
热议问题