Prevent Android WebView from attempting to fetch or capture resources such as CSS when using loadData() method

Context

To many, this situation might appear to be repetitive. However, I assure you that it is not.

My objective is to import html data into a WebView, while being able to intercept user hyperlink requests. During this process, I came across this helpful answer which fulfills my requirements, except for capturing requests for items like CSS files and images:

// Notify the webclient when a url is about to load
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request){
    return true;
}
// Perform an action when the desired URL is ready to load
@Override
public void onLoadResource(WebView view, String url){
    if( url.equals("http://cnn.com") ){
        // Customize behavior accordingly
    }
}

I have disabled automatic image loading, network loads, and execution of Javascript:

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

However, these adjustments do not prevent the capture of the mentioned requests.

Perhaps there is an alternate approach to intercepting link clicks, but the only options seem to be either this method or halting external resource loading altogether.

Query

Is there a way to stop WebView from capturing (or trying to load) resource requests such as CSS, JS, or images?

If preventing capture or loading is not possible, how can I distinguish between clicked links and web resources?

Thank you in advance!

Answer №1

To modify the behavior of WebViewClient's shouldInterceptRequest, you can create a custom response instead of fetching CSS, JS, images, etc.

For example:

    @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);
        }
    }

Here, R.raw.some_css contains:

    body {
      font-family: sans-serif;
    }

Please note:
Depending on the pages you are loading, this method might affect the page's appearance.

Answer №2

The answer is simple - it's not possible to do so.

Here's a more detailed explanation: the reason you can't achieve this is because web requests are designed to either capture everything or nothing at all. They are a broad concept that is not specific to individual resources like images or CSS files, meaning they don't recognize what those are. That's why your search for them comes up empty.

To work around this limitation, you can modify your approach by implementing logic in the shouldOverrideUrlLoading method. Instead of always returning true, only return true for URLs that you want to handle manually. For other types of requests such as CSS and JavaScript, return false so that the WebView will manage them on its own.

Here's an example:

@Override
public boolean shouldOverrideUrlLoading(WebView view, String  url) {
    // Skip handling CSS and JS files
    if (url.endsWith(".css") || url.endsWith(".js")) {
        return false;
    }

    return true;
}

Answer №3

Discovering a method to disregard automated WebView resource requests has been successful.

By filtering out requests within the initial second of WebView initialization, I can separate user-generated clicks from other interactions:

final Long time = System.currentTimeMillis()/1000;

// Set up a WebView and establish a WebViewClient for tracking link clicks
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) {
            // Implement actions here
        }
    }
};

Although untested without affecting JavaScript execution and automatic image loading, this solution is expected to function correctly:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Performing multiple ajax calls simultaneously in JavaScript using the React framework

Within my React application, I am faced with the challenge of handling an array of parameters (such as IDs) that need to be passed as parameters in a queue of ajax calls. The issue arises when this array exceeds 1000 items, causing the browser page to beco ...

Begin a SeleniumWebDriver session after Google Chrome has been launched beforehand

I am looking to create an automation using SeleniumWebDriver and Node.js, but I am facing an issue where I cannot start the automation if Google Chrome is already open and in use by the user. Currently, my workaround is to close all instances of Chrome be ...

Babel had a SyntaxError in test.jsx file at line 3, position 11 with an Unexpected token

Having trouble converting JSX to JS with Babel? If you're seeing an error like the one below, don't worry - we can help you fix it: The example code in test.jsx is causing a SyntaxError when transformed using babel test.jsx: SyntaxError: test ...

Is there a way for me to prevent a particular file from being cached by web browsers?

Is there a way to prevent Web Browsers from caching a particular file? For example: <img src="myImage.jpg" cache="false"></img> If possible, how can this be achieved? The code <meta http-equiv="cache-control" content="no-cache" /> ins ...

Is it possible to include a JavaScript script in a Laravel Blade file?

I have an Auth module from nwidart/laravel-Module. I am trying to include a script file in the Modules\Auth\Resources\views\layouts\app.blade.php file, like this: <body> ...... ... <!-- Scripts --> <script s ...

The PHP script receives an empty string value passed from JavaScript

I am struggling to pass a string from my JavaScript code to my PHP code. Here is the code snippet that triggers when I hit Enter in a text input: $('#user').keypress(function(e) { if(e.which == 13) { var val = $(this).val(); ...

What are the methods for detecting a change in a variable's value in JavaScript?

Although I am aware of Object.observe() and Object.prototype.watch(), these features are not widely supported. Fortunately, AngularJS does offer functionality to watch changes on objects. I am currently working on creating a script with similar capabiliti ...

Node.js error message: Unable to load HTTP module

Recently starting with Node.js, I decided to install the latest version (4.2.1) on my Windows 7 PC. However, when trying to include the HTTP module by writing: var http = require("http"); I'm receiving an undefined error message. Can someone help me ...

Guide on reusing javascript to toggle between image sources

I have a simple website with buttons that, when clicked, change the image being displayed. However, I find myself repeating code for each button, and I'm wondering if there is a more efficient solution to this problem. Here is an example of what I cu ...

step by step guide on swapping a portion of a JSON string

I need to eliminate the character "C" from keys that start with C_ in the following JSON string. Here is the JavaScript object I have: var jsonData= { key1:val1, key2:val2, C_100:1, C_101:2, C_102:3, } The desired output should look like this: v ...

How to Link Laravel 5 with Ajax?

I've implemented this Laravel code in my controller for the detach function. $input = Input::all(); $product= Products::findOrFail($input['product_id']); $product->tags()->detach($input['tag_id']); $product= Prod ...

Obtain value of dropdown selection upon change

What is the best way to retrieve the selected value in a drop-down menu when the ID dynamically changes with each refresh? Is it possible to access the particular selected value even when the ID changes? <select name="status" id="dropdown_status3352815 ...

Extract the body.req object within a loop in a Node.js application

I'm looking to efficiently parse and save the body of a POST request using Mongoose in Node.js. Is there a way to use a for loop to accomplish this task, rather than manually saving every property? My ideal solution would involve something like: for ...

The 'palette' property is not found on the Type 'Theme' within the MUI Property

Having some trouble with MUI and TypeScript. I keep encountering this error message: Property 'palette' does not exist on type 'Theme'.ts(2339) Check out the code snippet below: const StyledTextField = styled(TextField)(({ theme }) = ...

Display the progress bar's completion percentage during animation

Creating a progress bar using HTML with the following structure: <div class="progressbar"><div class="text">%0 Completed</div> <div class="progressbar_inner"></div> </div> Implemented jQuery code fo ...

Determine if an object hierarchy possesses a specified attribute

When passing a set of options as an object like this: var options={ sortRules:[ {...}, // rule 1 {...}, // rule 2 // etc. ], filterRules:[ {...}, // rule 1 {...}, // rule 2 // etc. ], etc ...

How does the Cluster module in Node.js compare to the Cluster module in Learnboost?

Node.js features its own Cluster core module (source: http://nodejs.org/docs/v0.8.3/api/cluster.html) while Learnboost has introduced a similarly named Cluster module as well (source: , https://github.com/LearnBoost/cluster). What are the differences betw ...

Removing gaps around rounded corners in jQuery UI accordions is a common issue that often arises when styling web elements

I am currently using jQuery UI Accordion to create collapsible sections that expand when clicked. In order to enhance the appearance, I have applied a background image to the header of each section like this: Check out my jQuery UI Accordion Demo here Up ...

What is the best way in Angular to focus on an input field using its name, model, or id?

My goal is to create a form where, upon leaving field one (blur), the system will check if the data inputted is the word "test". If the data does not contain this word, I want the focus to return to field 1. <form name='yourForm' novalidate n ...