25

I am using Nodejs and Express Js. Also I add NowJS to the Express Js to do some real-time stuffs.

In the configuration file I have

app.configure('production', function() {
var oneYear = 31557600000;
app.use(express.static(__dirname + '/public', { maxAge: oneYear }));
app.use(express.errorHandler());});

And I run the application using this command:

$ NODE_ENV=production node app.js

However, the files(images, css, js) seem not to be cached, they are always served as new file.

P/s: I have just tested it with localhost, the cache seems to work on localhost, however, when uploading to the server, the cache is not working anymore.

Tan Nguyen
  • 3,354
  • 3
  • 21
  • 18
  • possible duplicate of [How to totally prevent HTTP 304 responses in Connect/Express static middleware?](http://stackoverflow.com/questions/14641308/how-to-totally-prevent-http-304-responses-in-connect-express-static-middleware) – user956584 Jan 17 '15 at 19:39

4 Answers4

26

Express is built on Connect, and Connect provides the "static" middleware. Here's the code under the hood for the caching:

if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (maxAge / 1000));

You can find that code here:

https://github.com/senchalabs/connect/blob/master/lib/middleware/static.js#L147

So as you can see Express is sending a "Cache-Control" header to the browser, telling him to cache that file for a period. So this isn't a "load a file once and then always serve it to all clients", but more of a "tell each client to cache the file the first time he downloads it" (which means all the clients will have to download that file once before it's cached for them).

alessioalex
  • 62,577
  • 16
  • 155
  • 122
14

The following code does the job:

app.use(function (req, res, next) {
    if (req.url.match(/^\/(css|js|img|font)\/.+/)) {
        res.setHeader('Cache-Control', 'public, max-age=3600'); // cache header
    }
    next();
});
Augie Gardner
  • 2,749
  • 3
  • 25
  • 36
Felix
  • 341
  • 2
  • 10
10

The following code does the trick :

var cacheTime = 86400000*7;     // 7 days

app.use(express.static(__dirname + '/public',{ maxAge: cacheTime }));

However my public directory contains CSS as well as html files.

Is there a way i can cache css files only and not html.

I tried the setting "no-cache" in meta tag for html file but it didn't work.

vashishatashu
  • 7,720
  • 7
  • 29
  • 34
2

EDIT: I was wrong, see eug's comment below

Connect includes caching middleware: http://senchalabs.github.com/connect/middleware-staticCache.html

so it should be as easy as

app.use(express.cache(...));
app.use(express.static(...));
Praveen
  • 55,303
  • 33
  • 133
  • 164
Bulat
  • 2,435
  • 1
  • 15
  • 15
  • 7
    `connect.staticCache()` is now deprecated. – Kristopher Johnson Dec 11 '12 at 18:07
  • Any reference to this deprecation information? What should be used instead? – Mitar Feb 11 '13 at 23:04
  • What should be used instead, and more importantly, why was it deprecated? – skeggse Apr 11 '13 at 05:09
  • 2
    staticCache is not about HTTP caching, but caching the contents of the files within node so that they don't have to be read from the OS – eug Apr 27 '13 at 10:10
  • 2
    [Here's](https://github.com/senchalabs/connect/blob/master/lib/middleware/staticCache.js#L56-L57) the deprecation message. I guess you're supposed to use a "real" cache instead of the middleware. – superlukas Jul 01 '13 at 15:20