javafilterchromiumchromium-embeddedinterception

How to disable image loading in CEF/JCEF?


Is there a switch/flag that allows to do this? I spent hours finding those but couldn't find anything that works. The other thing I'm planning to do is intercept the cefRequest by adding my own CefRequestHandler, examine the resource type and if it matches RT_IMAGE, cancel the request. Everything seems easy except the part when I have to cancel a request. How do I stop/block/cancel a cefRequest? I probably should not be doing it this way but it doesn't work anyway:

public class CefClientRequestHandler extends CefRequestHandlerAdapter {

    @Override
    public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
        if (cefRequest.getResourceType().equals(CefRequest.ResourceType.RT_IMAGE)) {
            cefRequest.setURL("");
        }
        return false;
    }

    // more overides
}

Any ideas?


Solution

  • So here's a hack that works. The trick is to change the Request Method to HEAD, and because HEAD requests aren't returned the body, images won't be part of the response.

    public class CefClientRequestHandler extends CefRequestHandlerAdapter {
        @Override
        public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
            if (cefRequest.getResourceType().equals(RT_IMAGE)) {
                cefRequest.setMethod("HEAD");
            }
            return false;
        }
    
        // other overridden methods here...
    }
    

    I believe that this approach should be avoided mainly because of the following two reasons:

    1. Changing the method from GET to HEAD does not prevent CEF from making the request to the server. The overhead of opening a connection and handling a request is still there which makes it slower than simply blocking the request.

    2. I'm not sure if images won't be displayed if they are available from browser cache. Currently, I don't know of any methods to test this. Suggestions are welcome.

    Edit 1: Changing URL didn't work in the example I posted in the question because I was passing an empty String as the new URL. If we set the URL to some address that is not an "active" domain name (e.g. https://absolutegarbage-sdjdjfbskdfb.com), the request for that resource fails immediately:

    @Override
    public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
        if (cefRequest.getResourceType().equals(CefRequest.ResourceType.RT_IMAGE)) {
             cefRequest.setURL("https://yghjbnbk.com");
             System.out.println("LOL!");
        }
        return false;
    }
    

    As you can probably guess, this still is not the best solution. Please post an answer or comment if someone has found a better solution.

    Edit 2: Finally I have a clean working solution, thanks to user amaitland. We just have to pass a command line switch while setting the CefAppHandler. We can do that by overriding the method onBeforeCommandLineProcessing like this:

    CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
        @Override
        public void onBeforeCommandLineProcessing(String s, CefCommandLine cefCommandLine) {
            cefCommandLine.appendSwitch("disable-image-loading");
        }
    
        @Override
        public void stateHasChanged(CefApp.CefAppState state) {
            if (state == CefApp.CefAppState.TERMINATED) System.exit(0);
        }
    });