'Disable caching of a single file with try_files directive
I'm serving Angular 2 application with nginx using location section this way:
location / {
try_files $uri $uri/ /index.html =404;
}
try_files directive tries to find the requested uri in root directory and if it fails to find one it simply returns index.html
How to disable caching of index.html file?
Solution 1:[1]
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.
Solution 2:[2]
location / {
try_files $uri $uri/ /index.html;
}
location = /index.html {
expires -1;
}
Solution 3:[3]
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.
Solution 4:[4]
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;
}
Solution 5:[5]
Just to be safe :)
location = /index.html {
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
expires off;
}
Solution 6:[6]
I've managed to do it by adding a couple of lines in /etc/nginx/conf.d/default.conf
in the nginx:stable-alpine
docker:
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
add_header Cache-Control 'no-cache, no-store, must-revalidate'; # <-- added this
expires 0; # <-- added this
}
}
Caching is disabled for both /
and /index.html
paths.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Simon Ness |
Solution 2 | Dmitry MiksIr |
Solution 3 | Denys Vuika |
Solution 4 | |
Solution 5 | Synxmax |
Solution 6 | gRizzlyGR |