I was facing the issue of javascript being cached on users' browsers and not getting updated when changes went to production. Because the site uses multiple embedded iframes, just using f5 wasn't sufficient. The solution I went with is to load a script first that gets all the modified dates for the js files I need and then appends those dates to the js file in each page. Each page looks something like this:
<script type="text/javascript" src="get_dates"></script>//returns the dates for each file in array
<script type="text/javascript">
document.writeln('<script type="text/javascript" src="' + some_path + '?Mod=' + date_array[pos] + '"></script>...repeat for all scripts
</script>
The questions I have are:
How do you tell if the scripts are getting cached until the mod date changes? (I still want them to be cached, just not if they're updated)
How will the caching of the html page affect this?
Does using document.writeln(() affect caching? I.e. will they still be cached if you write the same exact script?
How do you tell if the scripts are getting cached until the mod date changes?
Just set the expiration to infinity (or, say, 1 year - that's long enough). Everytime your Mod parameter changes, the new file will be requested.
How will the caching of the html page affect this?
Not at all. The caching of the get_dates script will, though.
Does using document.writeln(() affect caching? I.e. will they still be cached if you write the same exact script?
No, it does not affect anything. The result - a <script> node referencing an external script will be the same.
Also read on How to force browser to reload cached CSS/JS files?
Sending the right headers from the server should control caching activity.
Or use a script loader to load the other scripts and apply cache-busting to the ones you need not cache.
Apply versioning to your js files in every production release.
Let say
Release1:
<script src="source.js?v1.0"></script>
Release2:
<script src="source.js?v2.0"></script>
and so on...
This way you still allowing clients to cache your js files but on a particular version.
Related
This question already has answers here:
How to force browsers to reload cached CSS and JS files?
(57 answers)
Closed 8 years ago.
When rolling out a new website change or web application change, sometimes browsers load old javascript or image files when you navigate to the site. Oftentimes it takes a manual refresh of the page for the browser to load in the newly updated files.
How can I make sure that after an update, users receive the most up-to-date files the first time they load the page, rather than having to manually refresh to clear out any cached files. Is there a very reliable way to do this through sending expires headers or last modified?
I assume you have a build script or a bunch of task scripts to help you with the repetitive process of updating the website/application . Since you tagged your question with javascript tag ,i will offer you a javascript based solution .
You could use (or alredy using) a task runner like Grunt or Glup or any other , and then run a cache busting task that will update your url's from this :
<script src="testing.js"></src>
<link href="testing.css" rel="stylesheet">
<img src="testing.png">
to this :
<script src="testing.js?v=123456"></src>
<link href="testing.css?v=123456" rel="stylesheet">
<img src="testing.png?v=123456">
This will prevent the browser from reusing your assets .
I know only one way how to do that - add some parameters to the end of the file URL.
E.g. you have image picture.png and instead of write it in html like this
<img src="path/to/picture.png">
you have to write it like this:
<img src="path/to/picture.png?specific_parameter_123">
So, changing of this parameter after '?' will force browser to load your picture (or something else) again because for browser the exact path was changed.
You can do it manually by changing parameter (or even generate it random every time by JS) or use something like Grunt and grunt-cache-breaker and it will generate unique URL of file based on md5 hash. So, once file was changed url will be also changed.
Also it is possible to do the same on server side. E.g. if you are using PHP you can try something like this: hash css and js files to break cache. Is it slow?.
More about query string here.
I have used a hash in some projects. That hash (md5 or something fast) is computed from the file contents of the used LESS/SASS files or JS modules. Each time something is changed, e.g. in the LESS source, the compiled CSS file will have a new filename.
You should enable client-side caching with a long caching time. The browser will store the CSS files locally. It only loads a new CSS file after a live-deploy.
Check the data you have available per the system.
For instance in Chrome, I'm working on a webapp (which is heavy, takes ~5 seconds) has lot of static resources (JS) files and CSS to load in the first time. To reflect changes of one JS, I need to reload the webpage with "Empty Clear Cache".
If there can be a way to only remove specific resource(s) JS files from cache (so to force refetch from server), my testing time can be reduced by great extent.
A technique is to add a random parameter to the url of assets you don't want cached.
Depending on what your server-side language is, you might be able to do something like the following:
<script src="my.js?_=<%= encode(new Date().toString()) %>"></script>
If you have a PHP backend, you could tack on a random number to the JS file URL:
<script type="text/javascript" src="/script.js?<?php echo time(); ?>"></script>
This will cause the browser to re-fetch it every time from server as the URL will differ.
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.css');
touch('/www/sample/file2.css') ?>
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.
I have a number of js files that I put in an another folder for ease of updating and for sharing between different pages. These files are called from another page and I use the
<script type="text/javascript" src="/js/file.js"></script>
notation.
This works fine but when I change something in one of these js files, the browser (chrome, firefox, safari) still loads the previous version without the changes, therefore not updating the js file it uses to the updated one. I tried to clean out the cache to force it to load the js file again (with the changes), but to no avail.
The only workaround that I have is to rename the external file to file2.js and include that in the page calling it but it is a tedious process because if I make another change I have to change the name to file3.js, etc.
Is there a way to force the browser to reload the original js and not use a previously stored one>
You can force the refresh by adding something unique in the URL:
In the code below the string "d6aa97d33d459ea3670056e737c99a3d" has to be generated for each request. You can use a timestamp, a hash, a random number, whatever you want.
Because of this, the browser will not reuse what he has in cache and will always download the JS file.
<script type="text/javascript" src="/js/file.js?d6aa97d33d459ea3670056e737c99a3d"></script>
You could try the classic technique of adding a random number to the query string.
<script type="text/javascript" src="/js/file.js?r=123"></script>
This would achieve the same thing as using a different file name (as far as the browser is concerned, this is a different URL) but you wouldn't have to rename your file.
Just use this:
<script type="text/javascript" src="/js/file.js?1"></script>
See the ?1 after the filename.
I have a list of js files, css and images which doesn't need to load from server every time, but if there is any update in files or bug fixes, only during that time I want to replace the files from browser cache, I know there is no access to browser cache, but is there any other ways to do so? My application will be used by specific users (known people), where I can install any program in their system, can anybody suggest me efficient way to do so? I don't want to load the files every time from server by setting 'no-cache'.
The most effective way to force the browser to refresh certain files at certain times is to add an arbitrary extra query string to the link:
<script type="text/javascript" src="http://mywebsite.com/js/scripttoload.js"></script>
then change to:
<script type="text/javascript" src="http://mywebsite.com/js/scripttoload.js?V=2"></script>
Next time the page is requested the browser will think this is a new file. There are loads of other ways with headers etc but this works well
No, there isn't.
Javascript doesn't have access to the cache - the browser doesn't expose this information to the javascript engine.
A commonly-used trick is to set the cache for the files to last for ages, so that they aren't requested again. However, when you want them to be updated, you can append a timestamp to the filename after a question mark. EG:
<link rel="stylesheet" href="style.css?123211212"/>
Every time the number changes, the browser thinks it's a different file and will re-download it. If the number doesn't change, then it uses the cached version.
What I do is, as part of the build process, rename all the statically referenced files to something involving their md5 hash. Then I set the headers so that they're cached for the max possible time. As soon as they change, they get a new name, so there's never an issue.
I've created a page that uses the CKEditor javascript rich edit control.
It's a pretty neat control, especially seeing as it's free, but I'm having serious issues with the way it allows you to add templates.
To add a template you need to modify the templates js file in the CKEditor templates folder. The documentation page describing it is here.
This works fine until I want to update a template or add a new one (or anything else that requires me to modify the js file).
Internet Explorer caches the js file and doesn't pick up the update. Emptying the cache allows the update to be picked up, but this isn't an acceptable solution. Whenever I update a template I do not want to tell all of the users across the organisation to empty their IE cache. There must be a better way!
Is there a way to stop IE caching the js file? Or is there another solution to this problem?
Update
Ok, I found this section in the CKEditor API that will allow me to use the "insert timestamp into the url" solution suggested by several people.
So the script now looks like this:
config.templates_files =
[
'/editor_templates/site_default.js?time=' + utcTimeMilliseconds
];
Thanks for your help guys.
You can add rand seed to your js file. I mean <script src='jsFile.js?seed=12345'
And every time you want to empty cache - change seed number
Update:
as I understood you have to write like this config.templates_files = [ '/mytemplates.js?seed=12345' ];
Youo can add a timestamp query parameter when you include your .js file..
so instead of <script type="text/javascript" src="somefile.js"></script> you can <script type="text/javascript" src="somefile.js?timestampgoeshere"></script>
this should make the file to always get reloaded (the timestamp needs to be dynamic and changing for each load of the page..)
I am afraid you'll have to hack into the FCKEditor code and force the client JavaScript to load fresh copy of the XML file. You can do so by appending a ?random=<a random number> to the URL of the XML file being requested. FCKEditor is opensource so you should be able to locate the lines the request the XML and modify accordingly.
Set Expires-Header accordingly, e.g. in Apache
ExpiresActive On
ExpiresByType text/javascript access
This is not recommended for a real web application, only for intranet scenarios because the files will not be cachable.
every time you load the js file, pass a variable of a random number as a variable.
src='/libs/js/myfile.js?4859487594573
same trick for ajax loaded files.
Multiple methods (don't need to do them all):
press ^F5 (control + F5) - that'll load without cache
set pragma/cache headers on sending
use a random variable in the GET query string
.NET / C# :
public static void DisallowBrowserCache( )
{
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false);
}
You could make ASP.NET write a js file to the outputstream (http://server.com/jsFile.aspx, set http headers), and control the caching behavior of the response with the above method.