Search code examples
cssnginxbrowser-cache

NGINX ignore hash css file and fetch any css that exists


I'm cache-busting with hashed css files (app-123456.css). The css file requests are proxied to a cdn with nginx. I need to keep the files statically named on the cdn, as there is a requirement to allow the customer to modify some css and re-upload the file. How can I pass the hashed file request to cdn and return the statically named file? For example a request to app-123456.css would return app.css, if it existed on the cdn. I'm trying to use try files but have been unsuccessful. Will cache-busting still work in this scenario, if the returned file is statically named? Thanks for any help.

location ~* (.+)\.(?:\d+)\.(css)$ {
  try_files $uri $1.$2 @styles;
}

location @styles {
  autoindex on;
  proxy_pass http://[url].net; # needs to go to http://[url].net/styles/
}

EDIT

location ~* (.+)-(?:\d+)\.(css)$ {
  try_files $uri $1.$2 @styles;
}

location @styles {
  autoindex on;
  rewrite ^(.+)-(?:\d+)\.(css)$ /styles$1.$2 break;
  proxy_pass http://[url].net; # needs to go to http://[url].net/styles/
}

Fixed

^(.+)\-([a-zA-Z0-9]*)\.(css)$

Solution

  • You need to modify the URI within the named location before passing it upstream with proxy_pass. This can be accomplished using a rewrite...break statement. See this document for details.

    For example, using your updated regular expression:

    location ~* ^(.+)\-(?:[a-zA-Z0-9]*)\.(css)$ {
        try_files $uri $1.$2 @styles;
    }
    location @styles {
        rewrite ^(.+)\-(?:[a-zA-Z0-9]*)\.(css)$ /styles$1.$2 break;
        proxy_pass http://...;
    }
    

    The above solution basically applies the same regular expression to the URI twice, which seems inefficient and redundant.

    If the /styles/ URI prefix is unique to the upstream server, you could perform the translation in the original try_files statement. See this document for details.

    For example:

    location ~* ^(.+)\-(?:[a-zA-Z0-9]*)\.(css)$ {
        try_files $uri $1.$2 /styles$1.$2$is_args$args;
    }
    location ^~ /styles/ {
        internal;
        proxy_pass http://...;
    }
    

    The ^~ operator give the prefix location a high precedence (see this document for details) and the internal directive prevents the URI from being directly accessible (see this document for details).