Ok, I'm almost giving up on this, but how can I disable the caching from Nginx for JavaScript files? I'm using a docker container with Nginx. When I now change something in the JavaScript file, I need multiple reloads until the new file is there.
How do I know it's Nginx and not the browser/docker?
Browser: I used curl
on the command line to simulate the request and had the same issues. Also, I'm using a CacheKiller
plugin and have cache disabled in Chrome Dev Tools.
Docker: When I connect to the container's bash, and use cat
after changing the file, I get the correct result immediately.
I changed my nginx.conf
for the sites-enabled
to this (which I found in another stackoverflow thread)
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|xml|html|htm)$ {
# clear all access_log directives for the current level
access_log off;
add_header Cache-Control no-cache;
# set the Expires header to 31 December 2037 23:59:59 GMT, and the Cache-Control max-age to 10 years
expires 1s;
}
However, after rebuilding the containers (and making sure it's in the container with cat
), it still didn't work. This here is the complete .conf
server {
server_name app;
root /var/www/app/web;
# Redirect to blog
location ~* ^/blog {
proxy_set_header Accept-Encoding "";
sub_filter 'https://testproject.wordpress.com/' '/blog/';
sub_filter_once off;
rewrite ^/blog/(.*) /$1 break;
rewrite ^/blog / break;
proxy_pass https://testproject.wordpress.com;
}
# Serve index.html only for exact root URL
location / {
try_files $uri /app_dev.php$is_args$args;
}
location ~ ^/(app|app_dev|config)\.php(/|$) {
fastcgi_pass php-upstream;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/app_dev.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|xml|html|htm)$ {
# clear all access_log directives for the current level
access_log off;
add_header Cache-Control no-cache;
# set the Expires header to 31 December 2037 23:59:59 GMT, and the Cache-Control max-age to 10 years
expires 1s;
}
error_log /var/log/nginx/app_error.log;
access_log /var/log/nginx/app_access.log;
}
Remember set
sendfile off;
or cache headers doesn't work. I use this snipped:The
expires
andadd_header
directives have no impact on NGINX caching the files, those are purely about what the browser sees.What you likely want instead is:
Though usually .js etc is the thing you would cache, so perhaps you should just disable caching entirely?
I know this question is a bit old but i would suggest to use some cachebraking hash in the url of the javascript. This works perfectly in production as well as during development because you can have both infinite cache times and intant updates when changes occur.
Lets assume you have a javascript file /js/script.min.js, but in the referencing html/php file you do not use the actual path but:
So everytime the file is changed, the browser gets a different url, which in turn means it cannot be cached, be it locally or on any proxy inbetween.
To make this work you need nginx to rewrite any request to /js/script.[0-9a-f]{32}.min.js to the original filename. In my case i use the following directive (for css also):
I would guess that the filemtime call does not even require disk access on the server as it should be in linux's file cache. If you have doubts or static html files you can also use a fixed random value (or incremental or content hash) that is updated when your javascript / css preprocessor has finished or let one of your git hooks change it.
In theory you could also use a cachebreaker as a dummy parameter (like /js/script.min.js?cachebreak=0123456789abcfef), but then the file is not cached at least by some proxies because of the "?".
What you are looking for is a simple directive like:
The above will not cache the extensions within the (). You can configure different directives for different file types.
I have the following Nginx virtual host(static content) for local development work to disable all browser caching:
I have the following nginx virtual host (static content) for local development work to disable all browser caching:
No cache headers sent:
Last-Modified
is always current time.