Caching - How Can I Force Clients To Refresh JavaScript Files - Stack Overflow
Caching - How Can I Force Clients To Refresh JavaScript Files - Stack Overflow
Asked 13 years, 11 months ago Modified 7 days ago Viewed 575k times
We are currently working in a private beta and so are still in the process of making fairly rapid
changes, although obviously as usage is starting to ramp up, we will be slowing down this
677 process. That being said, one issue we are running into is that after we push out an update with
new JavaScript files, the client browsers still use the cached version of the file and they do not
see the update. Obviously, on a support call, we can simply inform them to do a ctrl F5 refresh
to ensure that they get the up-to-date files from the server, but it would be preferable to handle
223 this before that time.
Our current thought is to simply attach a version number onto the name of the JavaScript files
and then when changes are made, increment the version on the script and update all references.
This definitely gets the job done, but updating the references on each release could get
cumbersome.
As I'm sure we're not the first ones to deal with this, I figured I would throw it out to the
community. How are you ensuring clients update their cache when you update your code? If
you're using the method described above, are you using a process that simplifies the change?
Share Follow edited Aug 3, 2011 at 19:04 asked Aug 28, 2008 at 14:30
Jason Plank AdamB
2,342 4 32 40 8,500 5 20 14
I have tried all "answers" below which are actually hacks. None of them can delete the exact image from the
cache. No wonder that this question got exactly 666 Likes (2022-05-28). – Obviously a browser feature that
is still missing. – Server-site no-cache headers seem to be the only way. – Avatar May 28 at 11:07
Sorted by:
Trending sort available
30 Answers
Highest score (default)
As far as I know a common solution is to add a ?<version> to the script's src link.
I assume at this point that there isn't a better way than find-replace to increment these
"version numbers" in all of the script tags?
You might have a version control system do that for you? Most version control systems have a
way to automatically inject the revision number on check-in for instance.
Share Follow edited Apr 17, 2015 at 21:22 answered Aug 28, 2008 at 14:34
Marco Bonelli Huppie
57.8k 20 112 117 11.1k 3 31 34
6 Does anyone know if IE7 ignores this? It seems to be ignoring the appended data and using the cached file
when I test in IE8 comparability view. – Shane Reustle Jan 20, 2011 at 20:18
5 I always knew the query strings are key-value pair as in ?ver=123. Thanks! :) – Ankur-m Feb 15, 2012 at
11:41
7 i think it's not about higher or lower version number but about changing the appended variables value to
something the browser couldn't have cached yet. – mgherkins Aug 5, 2013 at 10:43
51 For awareness: this is considered to be a hack. This method tricks the browser into thinking that a new file
is being specified, as it simply looks at the full file name without interpreting it. foo.js?1 is not the same
name as foo.js?2 , so the browser will think they are two different files. One downside is that both files
will simultaneously exist in the users' cache, taking up unnecessary space. – Lee White Sep 18, 2014 at
13:22
13 @LeeWhite Both files will be cached in the browser no matter how you approach the problem. Either
because they have different request params or different paths. So I don't think that's a disadvantage of the
request param approach. – Planky Nov 29, 2016 at 18:29
Appending the current time to the URL is indeed a common solution. However, you can also
manage this at the web server level, if you want to. The server can be configured to send different
109 HTTP headers for javascript files.
For example, to force the file to be cached for no longer than 1 day, you would send:
For beta, if you want to force the user to always get the latest, you would use:
5 can you please be more specific? – Kreker Jun 21, 2012 at 7:44
10 He is talking about the headers sent by the web server for each file. Should be configurable in Apache for
example. I think this would be the best approch – Pierre de LESPINAY Jul 25, 2012 at 12:16
2 For a development webapp, it's maybe a good solution. For a production site, where you do not want to
invalidate cache forever, it's not a good solution unless you know that each and every target client browser
has come to the site. It makes me think of a potential web server feature: adapt the max-age parameter
according to a configured deployment date. That would be awesome. – Claude Brisson Mar 15, 2017 at
13:48
Chrome REQUIRES these settings in order to cache properly. Without them, Chrome will cache a file
forever. Mozilla uses a much more reasonable default. See more at:
agiletribe.wordpress.com/2018/01/29/caching-for-chrome – AgilePro Jan 30, 2018 at 23:01
Google Page-Speed: Don't include a query string in the URL for static resources. Most proxies,
most notably Squid up through version 3.0, do not cache resources with a "?" in their URL even if a
46 Cache-control: public header is present in the response. To enable proxy caching for these
resources, remove query strings from references to static resources, and instead encode the
parameters into the file names themselves.
In this case, you can include the version into URL ex: http://abc.com/v1.2/script.js and use
apache mod_rewrite to redirect the link to http://abc.com/script.js. When you change the version,
client browser will update the new file.
I tried the ? solution and in IE8 and I get a javascript error. Mod rewrite is an option but in most cases we
wont have that much control over the server. I would prefer appending the version in the js file itself or
having a folder for each version – Karthik Sankar Jan 29, 2014 at 20:29
@Hắc Huyền Minh: But when the script shall be reloaded, it should not be reloaded from the proxy-cache...
– Stefan Steiger Dec 11, 2017 at 17:16
This answer is only 6 years late, but I don't see this answer in many places... HTML5 has
introduced Application Cache which is used to solve this problem. I was finding that new server
code I was writing was crashing old javascript stored in people's browsers, so I wanted to find a
way to expire their javascript. Use a manifest file that looks like this:
CACHE MANIFEST
# Aug 14, 2014
/mycode.js
NETWORK:
*
and generate this file with a new time stamp every time you want users to update their cache. As
a side note, if you add this, the browser will not reload (even when a user refreshes the page) until
the manifest tells it to.
Share Follow edited Dec 3, 2018 at 13:29 answered Aug 14, 2014 at 20:05
sk8terboi87 ツ amos
3,267 3 33 45 4,792 4 31 39
This solution is really good, as long as you remember to update the manifest file :) – Mattis Feb 9, 2015 at
9:40
34 Please read the documentation as this feature has been removed from the Web standards
developer.mozilla.org/en-US/docs/Web/HTML/… – Flavia Obreja Oct 26, 2015 at 14:59
1 FWIW, I ended up not using this solution. It was much easier to use/maintain the ?<version> approach.
– amos Dec 18, 2015 at 14:04
So every time you update the file the "filever" parameter changes.
How about when you update the file and your update results in the same file size? what are the
odds?
5 This uses PHP tags and if one uses PHP, it is indeed a good idea. – Jerther Apr 19, 2017 at 12:31
5 I think adding the changedate would be better than the filesize :) – Mazz May 24, 2017 at 9:22
6 My initial thought is to add a hash of the file instead of version. – Mike Cheel Sep 1, 2017 at 17:29
1 I assume that it also works if add a time stamp Unix, right? e.g ‘...file.js?filever=<?=time()?> – garanda Oct
6, 2017 at 18:36
4 use filemtime($file) it output the timestamp of the file, with time() you can't use cache as it change every
seconds. – neoteknic Nov 28, 2017 at 15:37
Not all browsers cache files with '?' in it. What I did to make sure it was cached as much as
possible, I included the version in the filename.
20
So instead of stuff.js?123 , I did stuff_123.js
Share Follow edited Apr 15, 2018 at 14:39 answered Sep 17, 2008 at 16:08
Aliaksandr Sushkevich Echo says Reinstate
10.3k 6 35 42 Monica
3,777 6 35 39
1 Could you please elaborate on what you did in .htaccess with mod_redirect? – Venkat D. Nov 8, 2011 at
6:15
3 A detailed explanation of this method can be found at particletree.com/notebook/… – Karl Bartel Dec 6,
2011 at 17:03
3 It would be great if you could include your .htaccess code within your answer for future reference.
– Fizzix Feb 29, 2016 at 6:54
2 Which browsers does not cache files with "?" in it? – rosell.dk Jun 17, 2019 at 9:08
The common practice nowadays is to generate a content hash code as part of the file name to
force the browser especially IE to reload the javascript files or css files.
13
For example,
vendor.a7561fb0e9a071baadb9.js
main.b746e3eb72875af2caa9.js
It is generally the job for the build tools such as webpack. Here is more details if anyone wants to
try out if you are using webpack.
12 BEFORE
<script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>"
type="text/javascript"></script>
18 While this is probably a god solution in a development environment, it isn't fit for production. This will
entirely disable the cache each time the page is loaded for the file. Imagine 10k page load per day with one
50Kb file, it represents 500Mb of Javascript file on a daily basis. – PhilDulac Jun 6, 2016 at 12:16
@PhilDulac you could change it from Ticks to return the string value of the day for instance, or the month,
or the week of the month. Ultimately it's just showing you how to use the ?v approach – alex Jun 15, 2016
at 15:16
3 @alex Indeed. I just wanted to warn that if the usage demonstrated in the answer makes its way to
production, it can have impacts that don't show in development. – PhilDulac Jun 15, 2016 at 16:02
2 A possible way to ensure that new copies get loaded once every day might be to use '<script
src="/Scripts/pages/common.js?ver<%=DateTime.Now.ToString("yyyyMMdd")%>" type="text/javascript">
</script>'. So it's load once at beginning of day, then cached. – Robb Sadler Sep 13, 2017 at 15:17
For ASP.NET I suppose next solution with advanced options (debug/release mode, versions):
I am using .Ticks (see my answer on this page) – Ravi Ram Jan 23, 2014 at 1:09
If you're generating the page that links to the JS files a simple solution is appending the file's last
modification timestamp to the generated links.
6
This is very similar to Huppie's answer, but works in version control systems without keyword
substitution. It's also better than append the current time, since that would prevent caching even
when the file didn't change at all.
I like this solution, since it's easiest to maintain. If you update a .js file, that's all you'll need to do. No need
to also update any references to the file, since your code will add the last updated timestamp automatically.
– NL3294 Jun 13, 2016 at 16:44
In PHP:
6 function latest_version($file_name){
echo $file_name."?".filemtime($_SERVER['DOCUMENT_ROOT'] .$file_name);
}
In HTML:
How it works:
In HTML, write the filepath and name as you wold do, but in the function only. PHP gets the
filetime of the file and returns the filepath+name+"?"+time of latest change
Share Follow edited Jul 26, 2016 at 14:03 answered Feb 3, 2013 at 11:48
Naman user1944129
1,471 16 32 61 1 1
We have been creating a SaaS for users and providing them a script to attach in their website
page, and it was not possible to attach a version with the script as user will attach the script to
6 their website for functionalities and i can't force them to change the version each time we update
the script
So, we found a way to load the newer version of the script each time user calls the original script
if($('script[src^="https://thesaasdomain.com/somejsfile.js?"]').length !== 0) {
init();
} else {
loadScript("https://thesaasdomain.com/somejsfile.js?" + guid());
}
Explanation:
The user have attached the script provided to them in their website and we checked for the
unique token attached with the script exists or not using jQuery selector and if not then load it
dynamically with newer token (or version)
This is call the same script twice which could be a performance issue, but it really solves the
problem of forcing the script to not load from the cache without putting the version in the actual
script link given to the user or client
The jQuery function getScript can also be used to ensure that a js file is indeed loaded every time
the page is loaded.
4
This is how I did it:
$(document).ready(function(){
$.getScript("../data/playlist.js", function(data, textStatus, jqxhr){
startProgram();
});
});
By default, $.getScript() sets the cache setting to false. This appends a timestamped query
parameter to the request URL to ensure that the browser downloads the script each time it is
requested.
9 We need to cache files if no changes happen. – Leo Lee Jan 18, 2016 at 2:45
My colleague just found a reference to that method right after I posted (in reference to css) at
http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack/. Good to see that others are
3 using it and it seems to work. I assume at this point that there isn't a better way than find-replace
to increment these "version numbers" in all of the script tags?
Share Follow edited Dec 15, 2011 at 15:22 answered Aug 28, 2008 at 14:42
Lightness Races in Orbit AdamB
371k 74 623 1026 8,500 5 20 14
1 This seems to work perfectly for both .css and .js files. – TNF Mar 9, 2021 at 8:38
In asp.net mvc you can use @DateTime.UtcNow.ToString() for js file version number. Version
number auto change with date and you force clients browser to refresh automatically js file. I
3 using this method and this is work well.
<script src="~/JsFilePath/JsFile.js?v=@DateTime.UtcNow.ToString()"></script>
Share Follow answered Dec 11, 2018 at 9:29
dragonal
74 4
1 As with other suggested solutions, this will cause the file never to be cached, which is usually undesirable.
As long as no changes have been made to the file you probably want the client to use the cached version
rather than download the unchanged file again every time. – Philip Stratford May 23, 2020 at 14:31
1 You can use below code for your reason, cache file with version number <script
src="~/JsFilePath/JsFile.js?v=@GetAppVersionNumber()"></script> – dragonal May 27, 2020 at 6:23
One solution is to append a query string with a timestamp in it to the URL when fetching the
resource. This takes advantage of the fact that a browser will not cache resources fetched from
2 URLs with query strings in them.
You probably don't want the browser not to cache these resources at all though; it's more likely
that you want them cached, but you want the browser to fetch a new version of the file when it is
made available.
The most common solution seems to be to embed a timestamp or revision number in the file
name itself. This is a little more work, because your code needs to be modified to request the
correct files, but it means that, e.g. version 7 of your snazzy_javascript_file.js (i.e.
snazzy_javascript_file_7.js ) is cached on the browser until you release version 8, and then
your code changes to fetch snazzy_javascript_file_8.js instead.
The advantage of using a file.js?V=1 over a fileV1.js is that you do not need to store multiple
versions of the JavaScript files on the server.
2
The trouble I see with file.js?V=1 is that you may have dependant code in another JavaScript
file that breaks when using the new version of the library utilities.
For the sake of backwards compatibility, I think it is much better to use jQuery.1.3.js for your
new pages and let existing pages use jQuery.1.1.js , until you are ready to upgrade the older
pages, if necessary.
2 Appending ?v=AUTO_INCREMENT_VERSION to the end of your url prevents browser caching - avoiding
any and all cached scripts.
Cache Busting in ASP.NET Core via a tag helper will handle this for you and allow your browser to
keep cached scripts/css until the file changes. Simply add the tag helper asp-append-
2 version="true" to your script (js) or link (css) tag:
Dave Paquette has a good example and explanation of cache busting here (bottom of page)
Cache Busting
Does this not work in regular ASP.NET? I tried adding the asp-append-version to my script tag and all the
browser sees is the script tag exactly as it appears in the source, including the asp-append-version
attribute. – tolsen64 Jul 26, 2017 at 20:03
This is a .NET Core attribute associated with Tag Helpers. It appends the script name with a version so that
the server/browser always sees the latest version and downloads – ccherwin Jul 31, 2017 at 22:42
location.reload(true);
2 see https://www.w3schools.com/jsref/met_loc_reload.asp
I dynamically call this line of code in order to ensure that javascript has been re-retrieved from the
web server instead of from the browser's cache in order to escape this problem.
Adding the onload="location.reload();" to my form allows me to get the new JS after a refresh
instead of relaunching my page. This a far more elegant solution. Thanks! – ZX9 Nov 6, 2019 at 14:37
Thanks, could use this with a check if the ip is recognised but hasn't been used to login since the last
update perform this on the index page after users initial login. – Fi Horan Nov 21, 2019 at 8:25
onload="location.reload(true);" The above did not work for me (using flask and current version of Chrome)
also: w3schools.com/jsref/met_loc_reload.asp – CodingMatters Dec 30, 2019 at 23:20
Athough it is framework specific, Django 1.4 has the staticfiles app functionality which works in a
similar fashion to the 'greenfelt' site in the above answer
2
Share Follow edited Aug 26, 2021 at 23:29 answered Oct 6, 2012 at 6:26
Trent
2,258 2 32 48
1 RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.(jpe?g|bmp|png|gif|css|js|mp3|ogg)$ [NC]
RewriteCond %{QUERY_STRING} !^(.+?&v33|)v=33[^&]*(?:&(.*)|)$ [NC]
RewriteRule ^ %{REQUEST_URI}?v=33 [R=301,L]
This causes a redirect which is performance-wise a suboptimal, but working solution. – twicejr Aug 1, 2017
at 9:03
You can add file version to your file name so it will be like:
1 https://www.example.com/script_fv25.js
And in your .htaccess put this block which will delete the version part from link:
RewriteEngine On
RewriteRule (.*)_fv\d+\.(js|css|txt|jpe?g|png|svg|ico|gif) $1.$2 [L]
https://www.example.com/script.js
Share Follow answered Jun 17, 2020 at 12:15
Mohamad Hamouday
1,532 18 17
If you are using PHP and Javascript then the following should work for you especially in the
situation where you are doing multiple times changes on the file. So, every time you cannot
1 change its version. So, the idea is to create a random number in PHP and then assign it as a
version of the JS file.
$fileVersion = rand();
<script src="addNewStudent.js?v=<?php echo $fileVersion; ?>"></script>
FRONT-END OPTION
1 I made this code specifically for those who can't change any settings on the backend. In this case
the best way to prevent a very long cache is with:
new Date().getTime()
However, for most programmers the cache can be a few minutes or hours so the simple code
above ends up forcing all users to download "the each page browsed". To specify how long this
item will remain without reloading I made this code and left several examples below:
// cache-expires-after.js v1
function cacheExpiresAfter(delay = 1, prefix = '', suffix = '') { // seconds
let now = new Date().getTime().toString();
now = now.substring(now.length - 11, 10); // remove decades and
milliseconds
now = parseInt(now / delay).toString();
return prefix + now + suffix;
};
// usage example:
let head = document.head || document.getElementsByTagName('head')[0];
let script = document.createElement('script');
script.setAttribute('src',
'//unpkg.com/sweetalert@2.1.2/dist/sweetalert.min.js' + cacheExpiresAfter(60 *
5, '?'));
head.append(script);
// this works?
let waitSwal = setInterval(function() {
if (window.swal) {
clearInterval(waitSwal);
swal('Script successfully injected', script.outerHTML);
};
}, 100);
Share Follow edited Oct 18, 2021 at 1:00 answered Aug 7, 2020 at 21:03
Luis Lobo
329 3 5
Simplest solution? Don't let the browser cache at all. Append the current time (in ms) as a query.
0 (You are still in beta, so you could make a reasonable case for not optimizing for performance.
But YMMV here.)
14 IMHO this is a poor solution. What if you are not in BETA and you push out an important update? – d-_-b
Aug 24, 2010 at 7:42
0
<head>
<meta charset="UTF-8">
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-
check=0, pre-check=0" />
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
</head>
Share Follow edited Mar 1, 2019 at 11:17 answered Mar 1, 2019 at 9:38
Mikev H.Ostwal
1,972 1 14 25 313 1 5 11
A simple trick that works fine for me to prevent conflicts between older and newer javascript files.
That means: If there is a conflict and some error occurs, the user will be prompted to press Ctrl-
0 F5.
looking like
Let this line of javascript be the last to be executed when loading the page:
In case that no error occurs the welcome greeting above will hardly be visible and almost
immediately be replaced by
<script>
var version = new Date().getTime();
0 var script = document.createElement("script");
script.src = "app.js?=" + version;
document.body.appendChild(script);
</script>
Feel free to delete this if someone's already posted it somewhere in the plethora of answers
above.
Highly active question. Earn 10 reputation (not counting the association bonus) in order to answer this question.
The reputation requirement helps protect this question from spam and non-answer activity.