Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express - Setting different maxAge for certain files

I'm building a single page application using Express for the backend and AngularJS for the frontend and I'm having some cache problems.

I'm not using express views, only serving files with express.static middleware.

My static files are in public/app or public/dist depending on enviroment (dist has minified files).

app.use app.router
app.use express.static(cwd + '/public/' + publicFolder, maxAge: MAX_AGE)

When requesting '/', app.router verifies if user is logged in, and if everything is ok then index.html is served via express.static (I just call next() in the controller). If user is not logged in, it gets redirected to login.html

My problem is that if I set maxAge, my index.html file gets cached and the first request to '/' doesn't go through router. I can enter the app even if I'm not logged in.

If I set maxAge to 0, the problem goes away, but I want to cache all my *.js and *.css files.

What is the correct approach to this kind of problems? Start using views? Different express.static mount points?

like image 359
martinpaulucci Avatar asked Oct 04 '22 15:10

martinpaulucci


1 Answers

You can always define individual routes without necessarily using views (although view templates aren't a bad idea). In this way you could define index.html just to apply the special case maxAge.

Just be sure to put the route before the static middleware.

If you wanted you could even use send, the same static server that the static middleware uses behind the scenes. Something like:

// install send from npm
var send = require("send");

app.get("/index.html", function (req, res) {
  send(req, "/index.html")
    .maxage(0)
    .root(__dirname + "/public")
    .pipe(res);
});

Or the more low level stream way, something like:

app.get("/index.html", function (req, res) {
  res.setHeader('Content-Type', 'text/html');
  res.setHeader('Cache-Control', 'public, max-age=0');

  // Note that you'd probably want to stat the file for `content-length`
  // as well.  This is just an example.

  var stream = fs.createReadStream(__dirname + '/public/index.html');
  stream.pipe(res);
});
like image 113
numbers1311407 Avatar answered Oct 07 '22 17:10

numbers1311407