Forced browser file cache refresh with javascript - javascript

I have python script in Splunk that generates .docx report.
When this report is created, I will receive link to this file that I use on my html/js dashboard to present the user with download link. The file is located inside the Splunk instance, Splunk has it's own cache but this one is cleared with version _bump.
The issue (probably) is that browser is caching the file and if I generate new report with different content then I keep downloading the old file instead of new one.
I am able to download the new version of the file only if I Empty cache and hard reload the webpage.
I can make a workaround by creating file with different name in the python but that like last possible solution. I would love to have just 1 report generated.
Is there a way how to clear this cache and make hard reload with javascript or how to force browser to download new version of the file?

Browsers cache the files based on the URL given. In order to control caches via the front-end browser, just add ?cachebust=TIMESTAMP to the URL, where TIMESTAMP is just the new Date().getTime(). Since you are adding it as a query parameter, it will still request the same resource from the back-end, so you don't have to do anything fancy server-side.
If you want to have it be versioned so you have more control over when the cache is busted, you could use a number that only gets incremented when you want to bust the cache. All that matters is the URL changes.
http://www.example.com/someFile.txt?cacheBust=109230110238

Related

How to force updated JS/CSS files to be delivered regardless of browser cache, without changing URL

I'm about to release a web application with a few pages. Each page is a Vue.js bundle. So on each page, there is a single javascript bundle & a single CSS file included, and a single div with a unique ID in the page where the app elements get mounted.
I need to be able to make updates to the static CSS/JS files without major service disruption. I'm using a Google Firebase backend for the application data, so if the client code doesn't update when an update is deployed, it could try to write to the database in the wrong format in an incorrect way. So, caching of the script files has been a problem.
I was initially under the impression that caches are invalidated when the hash of the file contents changes, but apparently that is not true. So, the core question is: How can I invalidate the browser cache of these files every time the content is updated?
What makes things complicated is that the web application may be embedded on clients' websites, by adding a small snippet to the page. And, I don't want to modify these snippets for every update - so I can't to change the filename with each version. E.g. in someoneswebsite.com.au/app/index.html:
<div id="my-app-mount"></div>
<script src="https://mywebapp.com.au/app/homepage.js"></script>
What won't work for me
Adding a query string or changing the filename with every update (Or other server-side tricks in PHP): I can't use any preprocessor as the snippet needs to be embeddable on other sites in HTML only.
Just setting a short TTL in the cache for these items. I need updates to work overnight, so I'd have to go down to just an hour or two. And this leads into the next point;
Disabling caching completely for these items: I don't want to flog my server with the extra traffic.
Just telling my users to do a hard-reload if they have any issues - this is a client-facing product.
My ideas for a solution so far
Change the filename with each upgrade app-1.0.js, app-1.1.js and so on, and add a 'bootstrap' script that gets the latest version based on a version string read from Firebase. However, this adds extra latency to every single page load as we need to hear from the database before loading the main JS payload.
In each javascript bundle, add a check to compare the app version with a version number retrieved from Firebase. If the script is out of date, we can programatically invalidate the cache and refresh the page (but how to do this?)
Some combination of HTTP cache headers, to always invalidate the cached copy if the hashed contents don't match the server.

Manual file caching in JavaScript

I have an HTML based project that works with media from other websites, which embeds images / songs / videos using their direct links. The system works perfectly so far, but I wish to make a change: As a lot of assets are accessed repeatedly by viewers, it would seem more optimal to cache them in a controlled way, so whenever certain media pops up you don't need to fetch it from the origin server each time. I never did this before so I don't know if and how it can be done.
To use an oversimplification: I have an embedded photo called "image.png" inside an image element, which will show up whenever I open the site. Currently it's simply defined as:
<img scr="https://foo.bar/image.png">
Works perfectly! However I want to make sure that when my site is accessed, you don't need to fetch that image from foo.bar each time: You will keep it in a local directory after downloading it once, from which the script can fetch and work with the file independently. For Firefox for instance, this subdirectory would be inside your ~/.mozilla/firefox/my_profile directory. Ideally it can be defined using a fixed name, so no matter which URL the website is opened from it uses the same cache path instead of each mirror of the project generating its own.
First, my script must tell the browser to download https://foo.bar/image.png and store it into this cache subdirectory. After that, it would need to generate a link to embed it directly from that subdirectory, so the URL I use would now be something of the following form:
<img scr="file://path_to_cache/image.png">
How do I do those two things, in a way that's compatible across popular web browsers? As a bonus, it would be useful to know if I can limit the size of this cache directory, so once it reaches say 100 MB the oldest items will be removed to stay under that size.
You could alternately add caching to your server's .htaccess file.
This site explains how: https://www.siteground.com/kb/leverage-browser-caching/
However this does not cache the image on the user's machine, it is cached on the server for quicker response.
You could use service workers to cache images on the user's machine.
https://developers.google.com/web/ilt/pwa/lab-caching-files-with-service-worker
Hope this helps.

Reading cache using JavaScript

This is Two questions:
1/ How can I read the cache stored by the browser if there's no permission restrictions?
2/ If the user browse into a website, is there a posibility of storing the page source code [HTML] in cache? (big website like youtube ..etc)
Thanks.
There is no way to read the cache manually - it all happens behind the scenes, if there is cache.
Yes, you can store the website's source code to the browser cache, but only the client-side part - HTML/CSS/JS/images/fonts/etc. It's called HTML5 Application Cache and it consists in a simple manifest file, which instructs the browser to download certain files locally and next time load them instead of downloading again. This cache you can programmatically update. Keep in mind, though, that most browsers have a limit (usually 5MB) of how much data you can store.
Hope that helps.

source code changes do NOT reflect immediately upon uploading them on my web host

This is not a programming question per se. I am using a free web host called getfreehosting. I am using their online file manager to transfer files. From time to time, the changes I make on source code do NOT reflect immediately after I upload them. I.e. when I run my application on Chrome, then go to view page source, I realize the JavaScript running is still the old version! In most cases this doesn't happen but when it does it is extremely frustrating. I've tried clearing the browser's cache. I even tried editing the file directly on their servers. Sometimes it solves the problem but other times it doesn't.
Is this a common issue encountered when transferring files to a web host? Or perhaps this is one of the downsides of using a free web host?
Thanks.
You can try clearing your browser's cache, or the ol' CTRL+F5 refresh trick. Otherwise, the hosting provider may be using a caching layer to help ease resource usage.
It is the responsibility of the server to indicate to the browser what the cacheable lifetime of the script files are when they are served to the browser (1 hr, 1 day, 1 month, etc...). This is a server side setting.
Caching is very important for both server-side efficiency and client-side performance so you don't want to defeat it completely.
You can either shorten the server-side setting for the cache lifetime or you can use a version number in your script files (like jQuery does) so that when you revise your script files, you give them a new filename like "myscript-v12.js" and update the corresponding HTML files to refer to the new filename. Then, as soon as the browser gets the new HTML file, it is guarenteed to get the new JS file because the new filename could never have been in the browser cache.
If this is just an issue for you personally while developing and revising your site, then just clear your browser cache after you upload new files and then when your browser loads that page, it won't have any version in the cache and will be forced to get the new version from the server.
There is a CACHE system in modern browsers.
Try clear cache before you browse your web site.

HTML5: Javascript to force offline cache rebuild?

Following html5rocks' tutorial, I hoped that window.applicationCache.update() would help to force re-building the offline cache.
(http://www.html5rocks.com/en/tutorials/appcache/beginner/#toc-updating-cache)
The purpose is to allow the users to hit an "update cache" button. This, because even files (css, img, etc.) are modified, the computer/tablet doesn't even check them for udpates. The users are left with old content.
How can this be done in JS?
If you are asking "how the client should know that the files are modified", then the answer is simple - the cache manifest should contain some unique identifier which gets updated when those files are updated. I generate the manifest with PHP and use a combination of monotonous increasing revision number and MAX(filemtime) from all the cached files - when the manifest file is different from the one the client has, it will check all the manifest-listed files for updates.
update() triggers the update check and downloads the updates if there are any, but it doesn't actually replace old cached data with the new.
swapCache() will swap out the old cached version with a newly downloaded one.
However, at that point your old JS has already created all the plumbing your page depends on...
My html5 application calls update() periodically, and when the cache update is downloaded, it just displays a button to the user saying "Install Updates!", which simply reloads the page - that way the newly downloaded cache files are applied when the user chooses to, without breaking his workflow.

Categories