Using Apache 2.4 on Debian 8.2, I am trying to enable caching of all css and js files. Caching of images works fine; that is, the browser receives a 304 status, so it doesn't download again. But I cannot get caching of other files working.
I use this inside a virtual host file:
<IfModule mod_expires.c>
<FilesMatch "\.(jpe?g|png|gif|js|css)$">
ExpiresActive On
ExpiresDefault "access plus 1 week"
</FilesMatch>
</IfModule>
The expires module is enabled. I did restart apache, cleaned browser cookies, etc. No success.
The response for a gif image, from browser developer tools:
Cache-Control:max-age=604800
Connection:Keep-Alive
Date:Wed, 25 Nov 2015 21:37:50 GMT
ETag:"4174a-4e69c97fbf080"
Expires:Wed, 02 Dec 2015 21:37:50 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.10 (Debian)
The response for a css file:
Accept-Ranges:bytes
Cache-Control:max-age=604800
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:135
Content-Type:text/css
Date:Wed, 25 Nov 2015 21:37:50 GMT
ETag:"5116-525639d271c78-gzip"
Expires:Wed, 02 Dec 2015 21:37:50 GMT
Keep-Alive:timeout=5, max=99
Last-Modified:Wed, 25 Nov 2015 20:50:52 GMT
Server:Apache/2.4.10 (Debian)
Vary:Accept-Encoding
It looks like the expires heading is set correctly, but the browser keeps requesting the file (200 OK).
I tried with Chrome and Firefox.
Summary:
1.) When I follow links inside the web site, the browser uses the cached files. But when I press F5, they re-download the css and js files, but they don't re-download images. Images give 304. That is fine.
2.) When I press Ctrl-F5, naturally enough, all files are re-downloaded. That's fine too.
3.) So the problem is how to enable caching (just like images) for other files. Why is apache discriminating between images and other files? I didn't put anything special to images in the config files.
Q: How to properly enable caching of css and js files?
Another Q: is there a special http header that says to the browser never to request the file. The reason is, sending even a request to check if the file is modified takes 100-200 ms, which is too much. I am sure the files will not be modified. And if they are modified, I can easily put a version string at the end of the css file, such as myFile.css?v=1.1 So I hope there should be a way to stop sending requests completely.
SOLVED
First, there is a bug in apache as mentioned in the answer below.
Second, there was a misunderstanding on my part. I guess this is how modern browsers work:
1.) Follow links inside a web site: No request is sent, even to check if the file has been modified.
2.) F5: Send a request. If file is not modified then the server responds 304.
3.) Ctrl+F5: Full download.
The behavior about F5 does not make sense to me. Anyway.
In case anybody needs it, here is a working solution that I put into virtual host file:
RequestHeader edit "If-None-Match" "^\"(.*)-gzip\"$" "\"$1\""
Header edit "ETag" "^\"(.*[^g][^z][^i][^p])\"$" "\"$1-gzip\""
LoadModule expires_module /usr/lib/apache2/modules/mod_expires.so
ExpiresActive On
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
ExpiresDefault "access plus 4 weeks"
</FilesMatch>
