How can you stop data URI from being cached as an image source?

I am facing an issue where I have an img-tag with a data-image base64 URI as the source. Browsers tend to cache this source, which is causing problems for me. If it were a normal URL, I could easily prevent caching by adding a random query-parameter value.

How can I prevent the caching of this data-image base64 URI source?

Here's an example of an img tag with a data-image base64 URI:

<img src="data:image/svg+xml;base64,PD94bWw==">

And here's an example of an img tag with a normal URL source along with a query param to avoid caching:

<img src="https://foo?1234RandomString">

In my case, since the original image is SVG, I could use a data-image SVG URI and add a custom attribute to the SVG to prevent caching, which works. I could also deploy the SVG as a file and use a URL with a query param, but I find both solutions quite unsightly.

PS: Why do I need it? I have a long list of img-tags and I want to implement lazy loading to generate the actual source URL lazily in vue3.

Consider this code snippet. Initially, the src is set to the data-image URI. When the image is lazily loaded, the actual source is created and set.

Issue: Lazy loading fails in Chrome if the initialSrc is cached for the first image, preventing the mechanism from working for subsequent images.

<img :src="mySource" loading="lazy" @load="onLoad">

const initialSrc = "data:image/svg+xml;base64,PD94bWw=="

const imageSrc = ref()
const onLoad = async () => {
      if (!imageSrc.value) {
        imageSrc.value = await createRealSrc();
      }
    };

const mySource = computed(() => imageSrc.value ?? initialSrc)

There are some doubts in comments that data URIs are actually loaded via a request. edit: Trigger warning. More nuanced than it seems. Take a look further down and in the comments. They are:

Screenshot of network tab that shows a GET request to a data URI

Some more clarifications:

Let's say you have two img-tags in your document:

<img src="http://image.png" loading="lazy">
<img src="http://image.png" loading="lazy">

In this scenario, the first img-tag will be loaded lazily, while the second will be immediately loaded after the first one because its src can be fetched from cache.

<img src="http://image.png" loading="lazy">
<img src="http://image.png?abc" loading="lazy">

In this scenario, both images will be loaded lazily as the URLs are different and cannot be taken from cache.

<img src="data:image/svg+xml;base64,PD94bWw==" loading="lazy">
<img src="data:image/svg+xml;base64,PD94bWw==" loading="lazy">

Here, the first img-tag will be loaded lazily, but the second will not be loaded lazily as it will be promptly loaded once the first one is loaded due to cache retrieval.

<img src="data:image/svg+xml;base64,PD94bWw==" loading="lazy">
<img src="data:image/svg+xml;base64,sdfsdfs==" loading="lazy">

In this last scenario, both images will load lazily since the URIs are unique and cannot be retrieved from cache.

Why does the img-tag load immediately instead of lazily when the image can be fetched from cache? The behavior I observe in Chrome leads me to believe that it may be an implementation detail or part of the current Chrome specification. It makes sense though - why trigger a lazy load when the data is already available in cache. However, I still require lazy-loading for my purpose as I intend to utilize it for performing expensive operations lazily.

Does using a data URI as a source really result in a GET request being made? According to the Chrome network tab, yes. Is it considered a real HTTP transaction? That remains uncertain. Edit: To clarify, there is no backend involved, so there is no TCP communication happening. Thus, it might not strictly adhere to real HTTP standards. However, internally Chrome treats it like a GET-request, recording a request/response in accordance with HTTP protocols. Real HTTP or not? Likely not purely authentic.

Is the data URI stored in cache? As per the Chrome network tab, it appears to be cached. My understanding suggests that image data gets stored in cache regardless of whether it originates from a file or a data URI.

Is the source loaded along with the image (and not beforehand) even when using a data URI? In my experience, I would affirmatively say yes. While I suspect it's part of the HTML spec, I lack concrete evidence to support this claim.

Answer №1

So much confusion has arisen, and I deeply regret that. Here are some innovative solutions that have been shared and that I believe deserve special attention:

Opt for a "plain" SVG-based data URI rather than a base64-encoded data URI.

By using a "plain" data URI, you can include a custom attribute with a random value to create a unique URI for the same image:

data:image/svg+xml,%3C%3Fxml version='1.0' **custom-attribute="random value"** encoding='UTF-8'%3F%3E%3Csvg width='282.21' height='48'...

If you are utilizing an SVG-based base64-encoded data URI, consider adding a base64-encoded comment.

Convert "<!-- random value -->" to base64 and append it to the base64-encoded data URI to make the URI distinct without altering the actual image. This method can also be used in place of the custom attribute mentioned earlier.

Incorporate a normal unique URL as the image source to streamline lazy loading processes.

This approach is particularly effective when dealing with lazy backend calls. Rather than lazily loading a data URI and subsequently executing a backend call onLoad, opt for a unique backend URL as the initial image source and initiate the backend call directly once the image source has been loaded lazily.

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

Tips for calculating the total of a virtual column through child associations in Sequelize

I have a network of 3 interconnected objects (A, B, and C). There can be multiple Bs associated with A, and multiple Cs associated with each B. For instance: A └───B │ └───C │ └───C └───B └───C Object ...

Verify the presence of both class and id before modifying the content of the h1 tag and automatically redirecting the page

I'm encountering some issues triggering my JS/JQ on an HTML5 page. Essentially, I want to verify the existence of the following ID and class: ID: page_blog CLASS: page current <section class="page current" id="page_blog" style="z-index: 99; lef ...

Is there a way to dynamically compute the height of rows in a VariableSizeList based on their index?

Is there a method to dynamically calculate the height of rows in React using the react-window library? Since it's uncertain whether all rows will have the same size, I find myself needing to utilize VariableSizeList. However, I'm wondering if the ...

Tips for working with elements in WebDriver that are created dynamically by JavaScript

As a novice in automation using Java and WebDriver, I find myself facing a particular issue: Browse for a specific customer Select a new customer type from a dropdown menu Click on the Save button Outcome: Upon trying to change the customer, a message p ...

Tips for converting a date string to a date object and then back to a string in the same format

I seem to be encountering an issue with dates (shocker!), and I could really use some assistance. Allow me to outline the steps I have been taking. Side note: The "datepipe" mentioned here is actually the DatePipe library from Angular. var date = new Dat ...

Issue: The error message "undefined variable 'angular'" appears when attempting to access offline files stored on a network drive

I have successfully developed offline forms using angular js v1.6.4, angular-ui-bootstrap, and angular-ui-router without the need for server hosting. When the package is saved on local storage, it functions perfectly on both IE and Chrome browsers. Howeve ...

Creating components and dynamic routing based on the current route

I'm in the process of creating "overview" pages for different sections within my app, each triggered from the root of that particular section. For example, localhost/hi should display the HiOverview component, And localhost/he should display the HeO ...

Troubleshooting Limitation Problem with Bootstrap Multiselect

I recently created a multiselect dropdown menu using Bootstrap Multiselect. I successfully set a limit on the number of options that can be selected (in this case, 5), and once the limit is reached, the additional options become disabled. Everything works ...

What is the best way to delete a nested child object using a specific identification number?

Here is the current json structure: $scope.dataList = [{ CompanyName: null, Location: null, Client: [{ ClientId: 0, ClientName: null, Projects:{ Id: 0, Name: null, } }] }]; I'm attempting to remo ...

What are the benefits of using Lifery Ajax URLs?

I'm currently using the Grails portlets plugin and I'm exploring how to properly route AJAX methods. It seems like <portlet:actionURL> is only able to map to methods that return models for GSPs, while <portlet:resourceURL> doesn&apos ...

Exploring the Functionality of Using Multiple Middlewares in Vue.js 3

For my web app project using vue.js 3 and vue-router, I followed a helpful tutorial on implementing middleware pipelines. The tutorial can be found at: https://blog.logrocket.com/vue-middleware-pipelines/. This tutorial demonstrated creating middleware to ...

Error message: A state has not been defined within the onload function

I'm facing an issue where I am attempting to assign a data URL of an image to a state in Vue.js, but it is not getting assigned properly. After converting a blob URL to a data URL, the state does not contain the correct data URL. While the imgSrc doe ...

The output of jQuery('body').text() varies depending on the browser being used

Here is the setup of my HTML code: <html> <head> <title>Test</title> <script type="text/javascript" src="jQuery.js"></script> <script type="text/javascript"> function initialize() { var ...

Using jQuery to fetch and read the source code of a specified URL

I'm facing an issue with extracting the source code of a website URL into a variable. Here is my current approach: <script type="text/javascript"> debugger; $(documnet).ready(function () { var timer = $.ajax({ type: ...

Utilizing an Angular foreach loop for restructuring JSON data

I currently have an ng-repeat function that outputs arrays of objects in the following format: [ {"day":"10","title":"day","summary":"summary","description":"ok","_id":"53f25185bffedb83d8348b22"}, {"day":"3","title":"day","summary":"summary","description" ...

Execute a function with parameters when a button is clicked dynamically using PHP

I am trying to execute a parameterised function in PHP using AJAX. Below is the code snippet of my dynamic button where I need to pass $sub_id to the delet(sub_id) function for executing some SQL: echo "<td><input type='submit' name=&a ...

Excessive geolocation position responses in Angular 5

I am trying to implement an Angular 5 component that will continuously fetch my current location every 3 seconds if it has changed. Here is a snippet of my code: export class WorkComponent implements OnInit { constructor(private userService: UserService ...

"Addclass() function successfully executing in the console, yet encountering issues within the script execution

I dynamically created a div and attempted to add the class 'expanded' using jQuery, but it's not working. Interestingly, when I try the same code in the console, it works perfectly. The code looks like this: appending element name var men ...

Developing a vanilla JavaScript web component with distinct HTML and JavaScript files

As I delve into creating vanilla JS web-components, I am exploring methods to keep the template HTML separate from the JS file, ideally in a distinct HTML file. I have examined various implementations of native JS web-component setups found notably here, ...

The NodeJS server encountered an issue when attempting to load the JavaScript modules

Hey everyone. I'm currently using Node.js and Express.js for the back end of my web application, but I keep running into issues with the server trying to bind references in the source code. Here's the structure of my app: src/ - static/ - ...