Nginx and Fontawesome v5 Issues - nginx

While this has been asked in various forms over the years, non of the answers have worked for me and the solution that is working makes no sense at all.
I'm hoping someone will be able to either make sense of why the solution solves the problem, or help me pin point the real issue.
The issue is that some of our woff2 font-awesome fonts don't display correctly, as can be seem by the output below
Request URL: https://example.com/fontawesome-webfont.af7ae505a9eed503f8b8.woff2?v=4.7.0
Request Method: GET
Status Code: 200
Remote Address: xxx.xxx.xxx.xxx:443
Referrer Policy: no-referrer-when-downgrade
content-encoding: br
content-type: text/html
Adding a location block as below seems to fix the issue, even though the location block itself does nothing (From my understanding at least)
location ~* \.(eot|otf|ttf|woff|woff2)$ {
}
I also have the follow mapped in my mime.types
font/ttf ttf;
font/woff woff;
font/woff2 woff2;
application/font-ttf ttf;
application/font-woff woff;
application/font-woff2 woff2;
application/x-font-ttf ttc ttf;
application/x-font-otf otf;
application/x-font-woff woff;
application/x-font-woff2 woff2;
We're using brotli and gzip for compression

I also faced the same issue. Posting my solution so that it might help someone.
Solutions that worked for me
Solution 1
location ~* \.(eot|otf|ttf|woff|woff2)$ {
access_log off;
log_not_found off;
# expires 30d;
add_header Access-Control-Allow-Origin *;
types {font/opentype otf;}
types {application/vnd.ms-fontobject eot;}
types {font/truetype ttf;}
types {application/font-woff woff;}
types {font/x-woff woff2;}
}
but if I add the above in the mime.type it is not working. so for that I tried below
Solution 2
Add this to mime.types
font/opentype otf;
font/truetype ttf;
application/font-woff woff;
font/x-woff woff2;
Due to the order of definition the mime.types is overridden by the default application/octet-stream
nginx.conf
Add the include /etc/nginx/mime.types; again inside your location block
location ~* \.(eot|otf|ttf|woff|woff2)$ {
access_log off;
log_not_found off;
# expires 30d;
include /etc/nginx/mime.types;
add_header Access-Control-Allow-Origin *;
}
Note
If you have cache enabled try to clear the server cache once. also if you are using CDN like cloudflare make sure you purge the cache after making this changes.

Related

nginx cache not working for CSS and JS scripts when checking using curl command

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?

Updating a website served with a large max-age

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

Rewriting paths in CSS & JS via nginx's sub_filter

I'm having a problem with nginx's sub_filter rewrite rules not working with CSS files. I'm serving content on a path (/site) and need all URLs in JS & CSS to be prefixed correctly.
I've specified the mime type when linking in the CSS. From the template:
<link href="/static/css/site.css" type="text/css" rel="stylesheet" />
nginx has sub filters enabled and I've explicitly specified to include text/css:
location /site {
access_log /opt/logs/test/nginx-access-site.log combined if=$loggable;
error_log /opt/logs/test/nginx-errors-site.log error;
rewrite ^(/site)$ $1/;
rewrite ^/site(.+) $1 break;
sub_filter "test.domain.tld" "test.domain.tld/site";
sub_filter "'/" "'/site/";
sub_filter '"/' '"/site/';
sub_filter "http:" "https:";
sub_filter_types text/html text/css text/javascript;
sub_filter_once off;
include proxy_params;
proxy_pass http://site_test$1$is_args$args;
proxy_redirect http://test.domain.tld/ https://test.domain.tld/site/;
}
The reference to the CSS file is rewritten correctly. From the HTML output:
<link href="/site/static/css/site.css" type="text/css" rel="stylesheet" />
The issue is it's not rewriting within the CSS file, so image paths are incorrect:
.sortable th .asc {
background-image: url("/static/img/up_arrow.gif");
}
I've tried being overly permissive without any difference:
sub_filter_types *;
Have I misunderstood the use of sub_filter? I assumed that because the CSS was being served directly by nginx it would also be rewritten.
I found the solution after some searching and wasted some time trying some that didn't work so hopefully this helps someone else searching and found this post.
Apparently, by default sub_filter works only for text/html. I tried various other options to enable for text/javascript text/css like this, but which didn't work:
sub_filter_types text/xml text/css text/javascript;
Finally got it working by filtering all types like this:
sub_filter_once off;
sub_filter_types *;
Remember to restart nginx and remember to clear cache on your browser.

NGINX Mime Types

I have the following problem:
https://my.domain.com/js/some_js_file.js
Is loading well but:
https://my.domain.com/some_other_folder/some_js_file.js
Brings up following error:
Refused to execute script from 'https://my.domain.com/some_other_folder/some_js_file.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
This is now happening after a security update of our loadbalancer.
I tried several things.
Add:
location ~ \.js {
add_header Content-Type application/x-javascript;
}
Or:
location ~ \.js {
add_header Content-Type application/javascript;
}
changed /etc/nginx/mime.types
From:
application/x-javascript js;
To:
application/javascript js;
Nothing works and I don't get it that not all files are throwing this error. Only the files in /some_other_folder/ or maybe outside of /js/

nginx: Serve file.css.xgz with the right headers

I have a stylesheet gzip compressed on disk and would like to serve it via nginx. It's named file.css.xgz and it should have
Content-Type: text/css
Content-Compression: gzip
So I added this to mime.types:
text/css css css.xgz;
And this to my server configuration:
location ~* \.xgz$ {
add_header Content-Encoding gzip;
}
Server is restarted for sure, but the content-type is still application/octet-stream (Content-Encoding is set as expected).
Try just "xgz" in the mime type in place of "css.xgz"

Resources