Exclude folders from caching - wordpress

In Plesk under Additional nginx directives I've added the following cache settings.
location ~* .(jpg|js|css)$ { #shortened
etag on;
if_modified_since exact;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
But in the wp-admin I have rewrites on the url's of these type of files.
How Do I exclude wp-admin/* and wp-includes/* from the block above?
Bit of background, I run a WordPress multisite in a subfolder. so
maildomain.com/wp-admin/stylesheet.css is actually located in
maildomain.com/wp/wp-admin/stylesheet.css

You can try to experiment with location parameter before caching directives, e.g.:
location ^~ /wp-admin/ {
}
location ~* .(jpg|js|css)$ { #shortened
etag on;
if_modified_since exact;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
UPD. Yes, checked it on my test lab and got the 403 error. I guess empty section is not enough and some directives should be added explicitly.
Managed to add exclusion like the one below:
location ~* "^/(?!wp-admin/|wp-includes/).*\.(jpg|js|css)$" { #shortened
etag on;
if_modified_since exact;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}

Related

URL from Origin has been blocked by CORS policy when Access-Control-Allow-Origin is set

I have a site that is requesting static files from a CDN. Many of the files are able to be used on the site, but some are being blocked by a CORS policy.
It's blocking html, json, woff, and woff2 files, but letting all other files by, including js, css, jpg and others.
It's a Magento 2 site using nginx. Here is the nginx.conf file where I have added the Access-Control-Allow-Origin:
location /static/ {
# Uncomment the following line in production mode
# expires max;
# Remove signature of the static files that is used to overcome the browser cache
location ~ ^/static/version\d*/ {
rewrite ^/static/version\d*/(.*)$ /static/$1 last;
}
location ~* \.(ico|jpg|jpeg|png|gif|svg|svgz|webp|avif|avifs|js|css|eot|ttf|otf|woff|woff2|html|json|webmanifest)$ {
add_header Cache-Control "public";
add_header X-Frame-Options "SAMEORIGIN";
include /etc/nginx/magento2-cors.conf;
expires +1y;
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
}
location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
add_header Cache-Control "no-store";
add_header X-Frame-Options "SAMEORIGIN";
include /etc/nginx/magento2-cors.conf;
expires off;
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
}
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
add_header X-Frame-Options "SAMEORIGIN";
include /etc/nginx/magento2-cors.conf;
}
And here is magento2-cors.conf:
add_header 'Access-Control-Allow-Origin' '*' 'always';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' 'always';
add_header 'Access-Control-Allow-Headers' 'x-requested-with' 'always';
add_header 'Access-Control-Max-Age' 86400 'always';
add_header 'Content-Length' 0 'always';
return 204;
}
What I don't get is why will CORS block some of the files and not others. All files are coming in through the same CDN. They are all coming from the static directory, which is what the above nginx.conf is referencing. js and css are apart of the same block as html and woff, but they aren't being blocked while html and woff are.
I've flushed browser cache and magento cache. I've restarted nginx multiple times, nothing seems to work.
Instead of using the include, see if putting
add_header Access-Control-Allow-Origin *;
without any if statement around it does the trick.
Try it after this line
location ~* \.(ico|jpg|jpeg|png|gif|svg|svgz|webp|avif|avifs|js|css|eot|ttf|otf|woff|woff2|html|json|webmanifest)$ {
You can also try putting the fonts in a subdirectory (ie: fonts) and see if that improves your situation.
If that doesn't work, try putting the * origin header immediately after
location /static/ {
Best of luck!

Disabling Cache-Control in Nginx for certain IPs

Static files on my server served with browser caching via Cache-Control headers:
location ~* \.(css|js|gif|jpe?g|png)$ {
expires 1h;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
Is it possible to disable this header for certain IPs so they would not cache any files?
P.S. I need it for users who log in as administrators to see the last changes.
The expires directive can be controlled by a variable, usually generated by a map directive. See this document for details.
For example:
map $remote_addr $expires {
default 1h;
10.1.2.3 -1;
}
server {
...
location ~* \.(css|js|gif|jpe?g|png)$ {
expires $expires;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
It is assumed that the add_header statements can remain, even if expires is set to -1 to disable the caching.

Define specific cache control header for selected file only

I'm setting up a Nginx sever (version 1.17.1) for Gatsby following up the recommendation at https://www.gatsbyjs.org/docs/caching/.
The snippet below is the portion my server {} block attempting implementing the recommended caching configuration;
location ~* \.(?:html)$ {
add_header Cache-Control "public, max-age=0, must-revalidate";
}
location /static {
add_header Cache-Control "public, max-age=31536000, immutable";
}
location ~* \.(?:css|js)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
location /sw\.js {
add_header Cache-Control "public, max-age=0, must-revalidate";
}
Equally tried an if statement in place of the location {} block for defining cache configuration for the service worker file, sw.js, as below;
if ($request_uri ~ ^sw\.(?:js)$) {
set $no_cache 1;
}
Unfortunately, all files get cached successfully as expected except sw.js.
What am I doing wrong and how can I fix it so as to effectively set cache control header for sw.js to public, max-age=0, must-revalidate?
I ended up with the following nginx configuration regarding caching for Gatsby.js:
location ~* \.(?:html)$ {
add_header Cache-Control "public, max-age=0, must-revalidate";
}
location /page-data {
add_header Cache-Control "public, max-age=0, must-revalidate";
}
location = /sw.js {
add_header Cache-Control "public, max-age=0, must-revalidate";
}
location /static {
add_header Cache-Control "public, max-age=31536000, immutable";
}
location ~* \.(?:js|css)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
#OP: With which configuration did you end up? Maybe you can edit this answer to match the perfect solution after all; for people searching for "caching nginx gatsby".
The order of precedence of location is described here https://nginx.org/en/docs/http/ngx_http_core_module.html#location
When an exact match is found (using the = modifier) the search terminates and regular expressions will not be checked, so you can use that for your sw.js:
location = /sw.js {
add_header Cache-Control "public, max-age=0, must-revalidate";
}

NGINX cache only images, css, fonts in a specific directory

location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico)$ {
expires 15d;
add_header Cache-Control "public, no-transform";
}
I have the code above which is supposed to cache these files for 15 days. how do I fix it so that only the files coming from /js, /css, /img will get cached instead of all?
Change the location rule to:
location ~ ^/(js|css|img)/*\.(js|css|png|jpg|jpeg|gif|svg|ico)$ {
expires 15d;
add_header Cache-Control "public, no-transform";
}
That should work

Set headers for .apk files served by nginx

In my server block I have
location / {
proxy_pass http://echocdn;
include /etc/nginx/mime.types;
add_header Cache-Control "max-age=31536000, private, no-transform, no-cache";
location ~* \.apk$ {
add_header Content-Type application/vnd.android.package-archive;
add_header Content-Disposition "attachment";
}
}
If I remove the inner location block, I can reach the APK file (and all other files).
With the block added, any .apk file returns a 404. How do I add the headers for APK files?
Note: Content types for other file types are handled well by the included mime.types, but even if I add the line for APK files as described How to download ".apk" as ".apk"? (not as ".zip") and https://blog.mypapit.net/2015/08/how-to-set-apk-mime-type-for-nginx-web-server.html it only returns a content-type of text/html for apk files.
maybe it's better not to set a header directly, for me it resulted in a double content-type.
but if you declare it in the location-block types it also works fine.
take a look:
location ~* \.apk$ {
types {
application/vnd.android.package-archive apk;
}
add_header Content-Disposition "attachment";
}
You need to have proxy_pass inside the apk block also. Nginx doesn't work like a programming language so you are not executing anything from the parent block.
Also for setting the content type using default_type directive
location / {
proxy_pass http://echocdn;
include /etc/nginx/mime.types;
#proxy_pass http://127.0.0.1:8082;
add_header Cache-Control "max-age=31536000, private, no-transform, no-cache";
location ~* \.apk$ {
default_type application/vnd.android.package-archive;
add_header Content-Type application/vnd.android.package-archive;
add_header Content-Disposition "attachment";
proxy_pass http://echocdn;
}
}
You can even handle this with a if
location / {
proxy_pass http://echocdn;
include /etc/nginx/mime.types;
#proxy_pass http://127.0.0.1:8082;
add_header Cache-Control "max-age=31536000, private, no-transform, no-cache";
if ($request_uri ~* \.apk$) {
default_type application/vnd.android.package-archive;
add_header Content-Type application/vnd.android.package-archive;
add_header Content-Disposition "attachment";
}
}
Try this:
location ~*.(apk)${
root /tmp/app;
add_header Content-Disposition attachment;
}
/tmp/app is your APK files full path.

Resources