I have a web-app I'm allowing users to add scripts to. These scripts are written in JavaScript and run in the user's browser. When developing new scripts to run locally, I've added a button to the app that allows you to load it from a locally running web server, (i.e. so you'd click on it and enter http://path.to.my.pc:12345/script.js). My app will fetch this script and append to the DOM.
These scripts are assumed to be ES6 modules and Chrome happily handles those, recursively importing correctly.
However when running locally, I also wanted the ability for users to "refresh" as they're developing such that the app will hit their server again to redownload the scripts. Chrome does not seem to want to do this. Specifically, despite the fact that my local test server has specified no-store as Cache-Control, Chrome doesn't care. Even if I cacheBust script.js (i.e.http://blah/script.js?cb=randomInt), this cacheBust parameter is not recursively passed to the imports.
Here's the text of my locally running dev server:
const express = require("express");
const serveStatic = require("serve-static");
const morgan = require("morgan");
function setHeaders(res, path) {
res.setHeader('Cache-Control', 'no-store');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
}
const app = express();
app.use(morgan('combined'));
app.use(serveStatic('./', { setHeaders });
app.listen(12345);
Is there something else I can do? I really don't want to force my users to run webpack. The idea is to keep this as simple and stupid as possible so they can just focus on writing their scripts.
Edit Update: Checking 'Disable Caching' in Devtools also does not cause Chrome to actually... not cache.
CodePudding user response:
In order to prevent the browser from caching the scripts that are loaded from your local web server, you can try setting the Expires
header to a date in the past. This will tell the browser that the resource has already expired and should not be cached.
Here is an example of how you can do this using the setHeader
method of the response
object in Express:
function setHeaders(res, path) {
res.setHeader('Cache-Control', 'no-store');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
// Set the Expires header to a date in the past.
res.setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT');
}
By setting the Expires
header in this way, the browser will not cache the scripts and will always fetch them from your local web server.
CodePudding user response:
Some ideas :
- Have you prior to everything, do "developer tools > application > clear storage" to avoid using previous server instance cached ?
- Have you tried "Cache-Control:no-cache, no-store" ?
- Have you tried on non Chrome browser ?
- Have you cleared all in client-side browser (ctr alt suppr) or hard reload (ctrl shift r) ?
I've the same need and in my node server i use
const nocache = require('nocache');
app.use(nocache());
app.set('etag', false);
And in client side, my query use only
'Cache-control', 'no-store'
CodePudding user response:
It sounds like you want to prevent the scripts from being cached in the user's browser when they are loaded from your local development server. The no-store
directive in the Cache-Control
header is intended to prevent caching, but it seems that Chrome is ignoring this directive in your case.
One thing you can try is adding an Expires
header to the response from your server with a date in the past. This should instruct the browser not to cache the response. You can do this by adding the following line to your setHeaders
function:
res.setHeader('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT');
Additionally, you can try adding a Vary
header to the response, with the value Cache-Control
. This tells the browser that the response may vary depending on the Cache-Control
header, and so it should not cache the response unless the Cache-Control
header allows it. You can add this header with the following line of code:
res.setHeader('Vary', 'Cache-Control');
It's also worth noting that the no-store
directive is intended to prevent caching by any cache (e.g. a proxy cache), not just the browser's cache. So it's possible that your local development server is running behind a proxy cache that is ignoring the no-store
directive. In that case, you may need to configure the proxy cache to respect the no-store
directive.
CodePudding user response:
There are a few things you can try to make sure Chrome is not caching your JavaScript files:
Use the Cache-Control: no-cache header instead of no-store. This will tell the browser to check with the server if the file has changed before using the cached version.
Use the Cache-Control: must-revalidate header in addition to no-cache. This will force the browser to revalidate the file with the server even if it hasn't changed.
Use a query parameter in the URL of your JavaScript file, such as script.js?timestamp=currentTimestamp. This will make the URL unique, so the browser will treat it as a different file and not use the cached version.
If all else fails, you can try clearing the browser's cache manually. In Chrome, go to Settings > Privacy and security > Clear browsing data, and select the "Cached images and files" option.
It's also worth noting that Chrome has a setting called "Disable cache (while DevTools is open)" in the Network panel of the DevTools. Enabling this will prevent the browser from caching any files while the DevTools are open, which can be useful for testing.