Disable caching of a single file with try_files directive

后端 未结 6 768
情书的邮戳
情书的邮戳 2021-02-01 16:42

I\'m serving Angular 2 application with nginx using location section this way:

location / {
  try_files $uri $uri/ /index.html =404;
}

try_file

相关标签:
6条回答
  • 2021-02-01 16:55

    Found a solution using nginx named locations:

    location / {
        gzip_static on;
        try_files $uri @index;
    }
    
    location @index {
        add_header Cache-Control no-cache;
        expires 0;
        try_files /index.html =404;
    }
    
    0 讨论(0)
  • 2021-02-01 17:09

    Thanks for a great answer Rem! As He Shiming points out with the accepted solution the caching headers don't get added when visiting the root e.g. www.example.com/, but do get added when visiting any deep link, e.g. www.example.com/some/path.

    After a lot of digging I believe this is because of the default behaviour of the ngnix module ngx_http_index_module, it includes index.html by default so when visiting the root /, the first location block's rules are satisfied, and index.html gets served without the cache control headers. The workaround I used was to include an index directive without specifying index.html in the first location block, forcing the root / to be served from the second location block.

    I also had another problem, I included a root directive in the first location block which broke deep links and is also a bad idea. I moved the root directive to the server level.

    Hope this helps, this is my solution...

    server {
      listen       80;
      server_name  localhost;
      root   /usr/share/nginx/html;
    
      location / {
        add_header X-debug-whats-going-on 1;
        index do-not-use-me.html;
        try_files $uri @index;                 
      }
    
      location @index {
        add_header X-debug-whats-going-on 2;
        add_header Cache-Control no-cache;
        expires 0;
        try_files /index.html =404;
      }
    }
    

    I've included debug headers to help make it absolutely clear what location block is serving what content. It's also worth noting the unintuitive behaviour of the add_header directive, essential reading if you also intend to add headers to all requests outside of a location block.

    0 讨论(0)
  • 2021-02-01 17:10

    You can use content-type mapping (should do the job for SPA with one .html file):

    map $sent_http_content_type $expires {
        default                    off;
        text/html                  epoch; # means no-cache
    }
    
    server {
      expires $expires;
    }
    
    
    
    0 讨论(0)
  • 2021-02-01 17:12

    I got the following setup working for my Angular apps, includes changes to index.html and nginx configuration:

    index.html

    <meta http-equiv="cache-control" content="max-age=0" />
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="expires" content="0" />
    <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
    <meta http-equiv="pragma" content="no-cache" />
    

    nginx.conf

    location / {
      try_files $uri $uri/ /index.html;
    }
    
    location ~ \.html$ {
      add_header Cache-Control "private, no-cache, no-store, must-revalidate";
      add_header Expires "Sat, 01 Jan 2000 00:00:00 GMT";
      add_header Pragma no-cache;
    }
    

    Works both when user navigates to "site.com" and "site.com/some/url" or "site.com/#/login". The "index.html" changes are to be on the safe side mainly.

    0 讨论(0)
  • 2021-02-01 17:14

    Just to be safe :)

    location = /index.html {
        add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
        expires off;
    }        
    
    0 讨论(0)
  • 2021-02-01 17:19
    location / {
      try_files $uri $uri/ /index.html;
    }
    
    location = /index.html {
      expires -1;
    }
    
    0 讨论(0)
提交回复
热议问题