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/
Related
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?
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.
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.
I have found an interesting problem.
I am trying to serve some gzipped files without the sources using NGINX's gzip_static module (I know the downsides to this). This means you can have gzipped files on the server that will be served with transfer-encoding: gzip. For example, if there's a file /foo.html.gz, a request for /foo.html will be served the compressed file with content-encoding: text/html.
While this usually works it turns out that when looking for index files in a directory the gzipped versions are not considered.
GET /index.html
200
GET /
403
I was wondering if anyone knows how to fix this. I tried setting index.html.gz as in index file but it is served as a gzip file rather then a gzip encoded html file.
This clearly won't work this way.
This is a part of the module source:
if (r->uri.data[r->uri.len - 1] == '/') {
return NGX_DECLINED;
}
So if the uri ends in slash, it does not even look for the gzipped version.
But, you probably could hack around using rewrite.
(This is a guess, I have not tested it)
rewrite ^(.*)/$ $1/index.html;
Edit: To make it work with autoindex (guess) you can try using this instead of rewrite:
location ~ /$ {
try_files ${uri}/index.html $uri;
}
It probably is better overall than using rewrite. But you need to try ...
You can prepare your precompressed files then serve it.
Below it's prepared by PHP and served without checking if the client supports gzip.
// PHP prepare the precompressed gzip file
file_put_contents('/var/www/static/gzip/script-name.js.gz', gzencode($s, 9));
// where $s is the string containing your file to pre-compress
// NginX serve the precompressed gzip file
location ~ "^/precompressed/(.+)\.js$" {
root /var/www;
expires 262144;
add_header Content-Encoding gzip;
default_type application/javascript;
try_files /static/gzip/$1.js.gz =404;
}
# Browser request a file - transfert 113,90 Kb (uncompressed size 358,68 Kb)
GET http://inc.ovh/precompressed/script-name.js
# Response from the server
Accept-Ranges bytes
Cache-Control max-age=262144
Connection keep-alive
Content-Encoding gzip
Content-Length 113540
Content-Type application/javascript; charset=utf-8
ETag "63f00fd5-1bb84"
Server NginX
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"