ChatGPT解决这个技术问题 Extra ChatGPT

Force browser to clear cache

Is there a way I can put some code on my page so when someone visits a site, it clears the browser cache, so they can view the changes?

Languages used: ASP.NET, VB.NET, and of course HTML, CSS, and jQuery.

A nice solution or workaround to "clear cache" can be found here: stackoverflow.com/a/43676353/2008111

J
Jeroen

If this is about .css and .js changes, one way is to to "cache busting" is by appending something like "_versionNo" to the file name for each release. For example:

script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.

Or alternatively do it after the file name:

script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.

You can check out this link to see how it could work.


This is a fairly good solution, and can even be automated by your build system (and should be). Stackoverflow, for example, uses this approach.
SO is using GET arguments now.
Better yet is to keep the filename as-is, but append the version number as a querystring parameter, i.e. script.js?v=1.2. (Or if you're not keeping track of versions, just use the file last-modified time, which is even easier to do). Not sure if that's what the previous commenter meant!
How does everyone do this with version control? Seems like a real pain.
@Doin, I briefly tested that technique, and it seemed to prevent Firefox and Chrome from caching the files altogether.
S
Sampson

Look into the cache-control and the expires META Tag.

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">

Another common practices is to append constantly-changing strings to the end of the requested files. For instance:

<script type="text/javascript" src="main.js?v=12392823"></script>


This won't help much in the case that it's already cached—since its cached, the server won't be queried, and thus can't responsd with no-cache. Also, that meta tag really shouldn't be used, as the note says, it'll break with web caches.
+1 what derobert said. Always better to use HTTP headers to suggest cache policy to clients and web caches but even that doesn't work to force a cache reload.
+1 for your second solution. I have this problem that the cache should be cleared only the first time after some administrator has made an update. This approach should solve that
Disabling cache completely is usually a really bad idea.
I am a beginner but I noticed the following the MDN Cache-Control doc: "If you mean to not store the response in any cache, use no-store instead. This directive is not effective in preventing caches from storing your response." But when I searched this page for "no-store", it seems nobody mentioned it. I must be misunderstanding something, what is it?
r
rsp

Update 2012

This is an old question but I think it needs a more up to date answer because now there is a way to have more control of website caching.

In Offline Web Applications (which is really any HTML5 website) applicationCache.swapCache() can be used to update the cached version of your website without the need for manually reloading the page.

This is a code example from the Beginner's Guide to Using the Application Cache on HTML5 Rocks explaining how to update users to the newest version of your site:

// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {

  window.applicationCache.addEventListener('updateready', function(e) {
    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
      // Browser downloaded a new app cache.
      // Swap it in and reload the page to get the new hotness.
      window.applicationCache.swapCache();
      if (confirm('A new version of this site is available. Load it?')) {
        window.location.reload();
      }
    } else {
      // Manifest didn't changed. Nothing new to server.
    }
  }, false);

}, false);

See also Using the application cache on Mozilla Developer Network for more info.

Update 2016

Things change quickly on the Web. This question was asked in 2009 and in 2012 I posted an update about a new way to handle the problem described in the question. Another 4 years passed and now it seems that it is already deprecated. Thanks to cgaldiolo for pointing it out in the comments.

Currently, as of July 2016, the HTML Standard, Section 7.9, Offline Web applications includes a deprecation warning:

This feature is in the process of being removed from the Web platform. (This is a long process that takes many years.) Using any of the offline Web application features at this time is highly discouraged. Use service workers instead.

So does Using the application cache on Mozilla Developer Network that I referenced in 2012:

Deprecated This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.

See also Bug 1204581 - Add a deprecation notice for AppCache if service worker fetch interception is enabled.


Does this imply you need to use and maintain a cache manifest file?
Warning: the Application Cache (AppCache) interface has been deprecated
So, what the current recommendation as of 2017?
2017: Use Service Workers.
any recommendation as of 2021?
C
Community

Not as such. One method is to send the appropriate headers when delivering content to force the browser to reload:

Making sure a web page is not cached, across all browsers.

If your search for "cache header" or something similar here on SO, you'll find ASP.NET specific examples.

Another, less clean but sometimes only way if you can't control the headers on server side, is adding a random GET parameter to the resource that is being called:

myimage.gif?random=1923849839

It's really better to properly version the files. This is a pretty big waste of bandwidth, and, probably more importantly, slows your site down a lot.
That really depends on the situation, doesn't it? If you are programming a CMS and need to make sure all changed resources are properly updated, there sometimes is no way around one of these two options.
Solutions like this should be voted into the negative. It's up to us to keep the CO2 footprint of the internet as low as possible.
as @derobert said, this is completely waste of bandwidth and also slows down page loading, because in each refresh you force the client to load the resource again, even if it's not changed, better way is to hash the file and send it as the query parameter, so it just change when file changes.
W
Wojtek Mazurek

I had similiar problem and this is how I solved it:

In index.html file I've added manifest: In section included script updating the cache: In section I've inserted onload function: In cache.manifest I've put all files I want to cache. It is important now that it works in my case (Apache) just by updating each time the "version" comment. It is also an option to name files with "?ver=001" or something at the end of name but it's not needed. Changing just # version 1.01 triggers cache update event. CACHE MANIFEST # version 1.01 style.css imgs/logo.png #all other files It's important to include 1., 2. and 3. points only in index.html. Otherwise GET http://foo.bar/resource.ext net::ERR_FAILED occurs because every "child" file tries to cache the page while the page is already cached. In update_cache.js file I've put this code: function checkForUpdate() { if (window.applicationCache != undefined && window.applicationCache != null) { window.applicationCache.addEventListener('updateready', updateApplication); } } function updateApplication(event) { if (window.applicationCache.status != 4) return; window.applicationCache.removeEventListener('updateready', updateApplication); window.applicationCache.swapCache(); window.location.reload(); }

Now you just change files and in manifest you have to update version comment. Now visiting index.html page will update the cache.

The parts of solution aren't mine but I've found them through internet and put together so that it works.


Shweta Gulati The manifest file should be in same folder as "index" file. What are the times it doesn't work?
@ShwetaGulati Yes, cache doesn't detect changes in html files - that's why You have to update version number in manifest file, because it is the one which is being checked for changes. It's really hard to help You, because I don't know details. Please, tell me if You have put all desired to be cached files in manifest? The path's should be relative to the manifest file. You can give me adress of Your website and I can tell what is the matter :)
@ShwetaGulati It's because browser caches some files automaticaly to make loading the page faster. It's default behavior and is dependednt on browser only so You can't set it in any way. Especially js files are on the scope of browser, because they are used usually on all pages on website so it's wise to cache them. There is no other way than write all file's names in manifest file to cache all the files. If You find any, tell me, because I need it too :)
The absolute path to your files doesn't matter. Relative path from adress matters 'cause browser sends the request for files. F.ex: I have domain example.com and it's on serwer names.com. My space on it is example.names.com. So I join my example.com domain to my server space example.names.com as redirect. To do that I need to set folder as a goal of this redirect. So If I want to have several sites on example.names.com I create folder "name1", set redirect to it and put all my files inside. Paths are counted from here. If I have name1\scripts\test.js in manifest file I write scripts\test.js.
For future reference, browsers have removed/depricated/disabled this.
P
Paulius Zaliaduonis

For static resources right caching would be to use query parameters with value of each deployment or file version. This will have effect of clearing cache after each deployment.

/Content/css/Site.css?version={FileVersionNumber}

Here is ASP.NET MVC example.

<link href="@Url.Content("~/Content/Css/Reset.css")?version=@this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />

Don't forget to update assembly version.


Thanks for this answer but how to do that when we add resources in the BundleTable please ?
In my case, this was returning "0.0.0.0" as the version. To get the version of the dll of your MVC app, use this instead: ?version=@ViewContext.Controller.GetType().Assembly.GetName().Version
I found that this prevents Firefox and Chrome from caching the content altogether.
z
zeeshan

I had a case where I would take photos of clients online and would need to update the div if a photo is changed. Browser was still showing the old photo. So I used the hack of calling a random GET variable, which would be unique every time. Here it is if it could help anybody

<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...

EDIT As pointed out by others, following is much more efficient solution since it will reload images only when they are changed, identifying this change by the file size:

<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"

This is not elegant at all, it would make the site reload the image every time wasting a lot of time downloading resources, a better solution would be to use filesize instead of a random number, this will make the cache only revalidate when the file actually changes
Or a hash of the image bytes
It all depends upon a user's requirements. For large number of photos scenario would be different than a few photos. Checking file size would save bandwidth, but would also add extra processing, potentially slowing down page load. In my case where pictures were changing quite frequently and it was critical business decision that user would get the most up-to-date ones, this was a perfect solution.
You could make it a static value in configuration even, this is by no means an ideal approach.
" would be much more useful!
J
John

A lot of answers are missing the point - most developers are well aware that turning off the cache is inefficient. However, there are many common circumstances where efficiency is unimportant and default cache behavior is badly broken.

These include nested, iterative script testing (the big one!) and broken third party software workarounds. None of the solutions given here are adequate to address such common scenarios. Most web browsers are far too aggressive caching and provide no sensible means to avoid these problems.


n
nPcomp

Updating the URL to the following works for me:

/custom.js?id=1

By adding a unique number after ?id= and incrementing it for new changes, users do not have to press CTRL + F5 to refresh the cache. Alternatively, you can append hash or string version of the current time or Epoch after ?id=

Something like ?id=1520606295


C
Community
D
Dave Swersky

Here is the MDSN page on setting caching in ASP.NET.

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True

If Response.Cache.VaryByParams("Category") Then
   '...
End If

L
Loïc Faure-Lacroix

Not sure if that might really help you but that's how caching should work on any browser. When the browser request a file, it should always send a request to the server unless there is a "offline" mode. The server will read some parameters like date modified or etags.

The server will return a 304 error response for NOT MODIFIED and the browser will have to use its cache. If the etag doesn't validate on server side or the modified date is below the current modified date, the server should return the new content with the new modified date or etags or both.

If there is no caching data sent to the browser, I guess the behavior is undetermined, the browser may or may not cache file that don't tell how they are cached. If you set caching parameters in the response it will cache your files correctly and the server then may choose to return a 304 error, or the new content.

This is how it should be done. Using random params or version number in urls is more like a hack than anything.

http://www.checkupdown.com/status/E304.html http://en.wikipedia.org/wiki/HTTP_ETag http://www.xpertdeveloper.com/2011/03/last-modified-header-vs-expire-header-vs-etag/

After reading I saw that there is also a expire date. If you have problem, it might be that you have a expire date set up. In other words, when the browser will cache your file, since it has a expiry date, it shouldn't have to request it again before that date. In other words, it will never ask the file to the server and will never receive a 304 not modified. It will simply use the cache until the expiry date is reached or cache is cleared.

So that is my guess, you have some sort of expiry date and you should use last-modified etags or a mix of it all and make sure that there is no expire date.

If people tends to refresh a lot and the file doesn't get changed a lot, then it might be wise to set a big expiry date.

My 2 cents!


S
Seak

I implemented this simple solution that works for me (not yet on production environment):

function verificarNovaVersio() {
    var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
    $.ajax({
        url: "./versio.txt"
        , dataType: 'text'
        , cache: false
        , contentType: false
        , processData: false
        , type: 'post'
     }).done(function(sVersioFitxer) {
        console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
        if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
            localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
            location.reload(true);
        }
    });
}

I've a little file located where the html are:

"versio.txt":

v00.5.0014

This function is called in all of my pages, so when loading it checks if the localStorage's version value is lower than the current version and does a

location.reload(true);

...to force reload from server instead from cache.

(obviously, instead of localStorage you can use cookies or other persistent client storage)

I opted for this solution for its simplicity, because only mantaining a single file "versio.txt" will force the full site to reload.

The queryString method is hard to implement and is also cached (if you change from v1.1 to a previous version will load from cache, then it means that the cache is not flushed, keeping all previous versions at cache).

I'm a little newbie and I'd apreciate your professional check & review to ensure my method is a good approach.

Hope it helps.


C
Community

In addition to setting Cache-control: no-cache, you should also set the Expires header to -1 if you would like the local copy to be refreshed each time (some versions of IE seem to require this).

See HTTP Cache - check with the server, always sending If-Modified-Since


J
Joish

There is one trick that can be used.The trick is to append a parameter/string to the file name in the script tag and change it when you file changes.

<script src="myfile.js?version=1.0.0"></script>

The browser interprets the whole string as the file path even though what comes after the "?" are parameters. So wat happens now is that next time when you update your file just change the number in the script tag on your website (Example <script src="myfile.js?version=1.0.1"></script>) and each users browser will see the file has changed and grab a new copy.


L
Luis H Cabrejo

Force browsers to clear cache or reload correct data? I have tried most of the solutions described in stackoverflow, some work, but after a little while, it does cache eventually and display the previous loaded script or file. Is there another way that would clear the cache (css, js, etc) and actually work on all browsers?

I found so far that specific resources can be reloaded individually if you change the date and time on your files on the server. "Clearing cache" is not as easy as it should be. Instead of clearing cache on my browsers, I realized that "touching" the server files cached will actually change the date and time of the source file cached on the server (Tested on Edge, Chrome and Firefox) and most browsers will automatically download the most current fresh copy of whats on your server (code, graphics any multimedia too). I suggest you just copy the most current scripts on the server and "do the touch thing" solution before your program runs, so it will change the date of all your problem files to a most current date and time, then it downloads a fresh copy to your browser:

<?php
   touch('/www/sample/file1.css');
   touch('/www/sample/file2.js');
?>

then ... the rest of your program...

It took me some time to resolve this issue (as many browsers act differently to different commands, but they all check time of files and compare to your downloaded copy in your browser, if different date and time, will do the refresh), If you can't go the supposed right way, there is always another usable and better solution to it. Best Regards and happy camping. By the way touch(); or alternatives work in many programming languages inclusive in javascript bash sh php and you can include or call them in html.


if the file is modified the timestamp is already changed anyway, so there is no benefit of forcing it again.
The touch command does not change the file at all. It changes the attribute of date and time, converting it to a newer version fooling the browser to download it as new copy.
U
Ujjwal Khare

For webpack users:-

I added time with chunkhash in my webpack config. This solved my problem of invalidating cache on each deployment. Also we need to take care that index.html/ asset.manifest is not cached both in your CDN or browser. Config of chunk name in webpack config will look like this:-

fileName: [chunkhash]-${Date.now()}.js

or If you are using contenthash then

fileName: [contenthash]-${Date.now()}.js


Please format your answer, for a better visualization. We use markdown. You can edit your answer.
A
Ayesh Ruwandeniya

This is the simple solution I used to solve in one of my applications using PHP.

All JS and CSS files are placed in a folder with version name. Example : "1.0.01"

root\1.0.01\JS
root\1.0.01\CSS

Created a Helper and Defined the version Number there

<?php
function system_version()
{
    return '1.0.07';
}

And Linked JS and SCC Files like below

<script src="<?= base_url(); ?>/<?= system_version();?>/js/generators.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="<?= base_url(); ?>/<?= system_version(); ?>/css/view-checklist.css" />

Whenever I make changes to any JS or CSS file, I change the System Verson in Helper and rename the folder and deploy it.


A
Asn

I had the same problem, all i did was change the file names which are linked to my index.html file and then went into the index.html file and updated their names, not the best practice but if it works it works. The browser sees them as new files so they get redownloaded on to the users device.

example: I want to update a css file, its named styles.css, change it to styless.css

Go into index.html and update , and change it to


T
Tim Crone

Do you want to clear the cache, or just make sure your current (changed?) page is not cached?

If the latter, it should be as simple as

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

I read about this approach recently in a Chrome posting, and I only found consistent results on a handful of live servers, localhost and Windows fileshares... with Firefox 3.6.