I have a SPA website (VueJS) that I've begun updating on a daily basis. When I was new to the entire process, I borrowed bits and pieces of my nginx configuration from multiple sources and ended up serving all the files in my website with Cache-Control: max-age=31536000.
After having users complain that they're unable to find my recent changes, I've inclined to think that it may be due to the browser caching everything till 2037 :(. This hypothesis is supported by the fact that following my advice of CTRL+F5 fixed their issue.
I have since updated the website different cache rules, but the browser doesn't seem to be hitting my server to fetch these newer rules.
map $sent_http_content_type $expires {
default off;
text/html off;
text/css off;
application/javascript off;
application/x-javascript off;
}
...
server {
...
location / {
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
...
}
}
Is there any way to undo this? Do I have to pack up and move to another domain?
If you have had far future Cache-Control lifetime set for all pages, and have a solid user base who were visiting your site when it was effective... then the short answer is: YES.
There is no way to undo use of browser cache as it will not check for new cache policy before currenly cached assets (your pages also, in this case) will not expire..
But you can just account for the fact that people tend to change browsers, run OS optimizer (which clear caches), or have an email campaign for users you know to instruct them to clear browser caches.
Not a good situation any way you look at it.
The setting that seem to work for me is the following using map is the following and I don't need to setup no-cache header any where else.
server {
add_header X-Frame-Options SAMEORIGIN always;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
expires $expires;
...
}
map $sent_http_content_type $expires {
default off;
"text/html" epoch;
"text/html; charset=utf-8" epoch;
"text/css" epoch;
"application/javascript" epoch;
"~image/" max;
}
This guide has help understand.
https://www.digitalocean.com/community/tutorials/how-to-implement-browser-caching-with-nginx-s-header-module-on-ubuntu-16-04
Related
I have an nginx conf file containing some generic lines that I deploy on several websites. Among those lines I have this:
add_header X-Frame-Options "SAMEORIGIN";
For certain websites I want to deploy some custom lines. For example there are a few websites for which I want to deploy the following because I want to allow them to be loaded in some iframes:
add_header X-Frame-Options "";
So, those websites conf files end-up containing something like this:
# some generic settings
add_header X-Frame-Options "SAMEORIGIN";
...
# some custom settings
add_header X-Frame-Options "";
...
The problem is that the second add_header X-Frame-Options doesn't override the first.
I also tried to switch the settings and I put the custom ones first and then the generic ones. So the conf file looked like this:
# some custom settings
add_header X-Frame-Options "";
...
# some generic settings
add_header X-Frame-Options "SAMEORIGIN";
...
But again, the setting for X-Frame-Options was "SAMEORIGIN" and not "".
My question is: is there any possibility to override that X-Frame-Options add_header setting once it is set?
I'm running nginx 1.20 on a Ubuntu 18.
You can override it by setting Content-Security-Policy frame-ancestors directive. For all but legacy browsers, this will override X-Frame-Options. Try
Content-Security-Policy: frame-ancestors 'self' *;
You might not need 'self' (equals to XFO SAMEORIGIN), you can test without it.
According this doc we need to remove page-data.json from being cached.
Here's my location directive on nginx
location /page-data {
add_header Cache-Control "public, max-age=0, must-revalidate";
}
For some reason the header response is still max-age=3660000
How would I go about making sure that all the page-data.json from the path /page-data/ isn't cached.
I'm trying to follow this guide: https://www.digitalocean.com/community/tutorials/how-to-implement-browser-caching-with-nginx-s-header-module-on-ubuntu-16-04
but every time I execute curl -I http://myjsfile.com/thejsfile.js it doesn't return the cache property
i.e this one:
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Cache-Control: no-cache
this is what I have in my sites-available file. though there are 2 in there the default and our custom one for Certbot SSL certs. I did apply this to those 2 files.
# Expires map
map $sent_http_content_type $expires {
default off;
text/html epoch;
text/css max;
application/javascript max;
~image/ epoch;
}
So I'm not sure it's caching it and when I checked it using gtmetrix it still gets an F for browser caching.
I also tried this one: NGINX cache static files
and I have this in my nginx.conf inside http
server {
location ~* \.(?:ico|css|js)$ {
expires 30d;
add_header Vary Accept-Encoding;
access_log off;
}
}
but it still didn't work when I checked using the curl command.
so can someone enlighten me on what I'm doing wrong here or is this not the best approach to cache JS and CSS files?
I need to add the below X-Frame options in the nginx CF.
add_header X-Frame-Options "SAMEORIGIN";
I am using Cloud Foundry Staticfile buildpacks.
If I edit nginx.conf directly, it is getting removed whenever I deploy my application. So it is recommended to added through Staticfile buildpack.
But I don't know the exact value for the x-frame options.
Reference: https://docs.cloudfoundry.org/buildpacks/staticfile/index.html
Correct, you do not want to edit the config file directly. Your change will disappear the next time your app is restarted, restaged, recreated, crashes or even the next time the platform moves the app due to maintenance.
If you follow the instructions for adding custom Nginx configuration, you can put the configuration into a snippet & the Nginx configuration generated by the Staticfile buildpack will automatically read your config snippet.
Hope that helps!
Nginx.conf file Enable X-Frame-Options
location ~* \.(?:html)$ {
try_files $uri =404;
add_header Cache-Control 'no-cache, no-store, must-revalidate, max-age=0';
add_header X-Frame-Options 'SAMEORIGIN';
add_header X-Frame-Options 'DENY';
add_header Content-Security-Policy "frame-ancestors 'self';";
expires 0;
}
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.
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
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 "";