Question

I'm trying to tell nginx to cache some of my assets (js, css) forever, or at least for a very long time.

The idea is that once an asset bundle is compiled and published with an /assets/ URI prefix (e.g. /assets/foo-{fingerprint}.js) it stays there and doesn't ever need to change.

The internets told me I should write the following rule:

location ~ ^/assets/.*-([^.]+)\.(js|css)$ {
  gzip_static on; # there's also a .gz of the asset
  expires max;
  add_header Cache-Control public;
  add_header Last-Modified "";
  add_header ETag "";
  break;
}

I would expect this would result in responses with HTTP code 304 "Not Modified", but what I get is a consistent HTTP 200 (OK) every time.

I have tried some other approaches, for instance:

a) explicitly setting modification time to a constant point in time in the past;

add_header Last-Modified "Thu, 01 Jan 1970 00:00:00 GMT";

b) switching to If-None-Match checks;

add_header ETag $1;
if_modified_since off;

However, the only thing that really worked as needed was this:

add_header Last-Modified "Thu, 01 Jan 2030 00:00:00 GMT";
if_modified_since before;

I'm lost. This is contrary to everything I thought was right. Please help.

Was it helpful?

Solution

You should change your internets, since they give you wrong advices.

Just remove all add_header lines from your location (as well as surplus brake):

location ~ ^/assets/.*-([^.]+)\.(js|css)$ {
   gzip_static on; # there's also a .gz of the asset
   expires max;
}

and read the docs from the true Internet: http://nginx.org/r/expires and http://tools.ietf.org/html/rfc2616

OTHER TIPS

It seems part of my configuration. During my researching I realized that browser uses heuristic analysis to validate requests with ConditionalGet headers (E-Tag, Last-Modified). It makes a lot of sense for back-end responses, so you can handle that to save server resources.

But in terms of static files (js, css, images), you can tell browser to serve them straight away without any Conditional Get validation. It is helpful if you update file name if any change takes place.

This part of configuration makes it happen:

add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top