httpcachingnginxlast-modifiedif-modified-since

Indefinitely caching a HTTP response via Nginx fails


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.


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 https://www.rfc-editor.org/rfc/rfc2616