I have a problem setting the cache expire date on my website. This is the code I use in .htaccess file:
<FilesMatch "\.(xml|txt|css|js)$">
Header set Cache-Control "max-age=7200, proxy-revalidate"
</FilesMatch>
The file types I mentioned should have an expire date of 2 hours, but after hard refresh I see that all these files have an expiration date of one week. As an example, I select the .css file in Chrome inspect page and I see this information:
Accept-Ranges:bytes
Cache-Control:max-age=8000, proxy-revalidate
Connection:close
Content-Encoding:gzip
Content-Length:20229
Content-Type:text/css
Date:Wed, 26 Jul 2017 09:02:31 GMT
ETag:"1c8c1-55513528cb363-gzip"
Expires:Wed, 02 Aug 2017 09:02:31 GMT
Last-Modified:Mon, 24 Jul 2017 17:12:41 GMT
Server:Apache
Vary:Accept-Encoding
The cache control max age is working, but why is the file's expire date only one week after? Is this some kind of server cache or I am doing something wrong?
Just found out that cache-control:max-age always overwrites the expires tag so everything is ok.
Related
I'm trying to apply a no cache header to the style.css file in the child theme of my WordPress site, using the .htaccess file. I want to avoid having to clear my browser cache every time I make CSS styling changes to the site, in order to see the changes. Currently my cache control looks like this -
<Files ~ https://my-domain.org.au/wp-content/themes/church-suite_child_theme/style.css>
FileEtag None
<ifModule mod_headers.c>
Header Unset ETag
Header Set Cache-Control "max-age=0, no-store, no-cache, must-revalidate"
Header Set Pragma "no-cache"
Header Set Expires "Thu, 30 June 2022 00:00:00 GMT"
</ifModule>
</Files>
It doesn't appear to be working. I'm using the Network Inspector in Chrome Dev Tools to view the network requests. The following is returned when I refresh the page and inspect the request -
RESPONSE HEADERS,
cache-control: max-age=31536000
content-encoding: br
content-type: text/css
date: Fri, 12 Nov 2021 01:41:45 GMT
etag: W/"6188f369-73b"
expires: Sat, 12 Nov 2022 01:41:45 GMT
host-header: 8441280b0c35cbc1147f8ba998a563a7
last-modified: Mon, 08 Nov 2021 09:52:41 GMT
server: nginx
vary: Accept-Encoding
x-proxy-cache-info: DT:1
I'm already aware of caching files with Apache. I'm writing unit tests for a library and I have one PHP file that prints the current microtime. I use it to verify if the file has changed between two requests.
My problem : the returned content is always different, even if I force caching in .htaccess with :
ExpiresActive on
ExpiresDefault "access plus 1 year"
Header append Cache-Control "public"
When I watch the response headers in the developer tools, everything seems fine :
Cache-Control:max-age=31536000, public
Connection:Keep-Alive
Content-Length:14
Content-Type:text/html
Date:Thu, 06 Nov 2014 09:21:30 GMT
Expires:Fri, 06 Nov 2015 09:21:30 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.7 (Win32) PHP/5.5.8
X-Powered-By:PHP/5.5.8
If I do this:
<IfModule mod_expires.c>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|mp3|mp4|css|js|php)$">
ExpiresActive On
ExpiresDefault "access plus 30 days"
</FilesMatch>
</IfModule>
It doesn't set properly the Expire header, whereas if I "force" it by hand like this:
<IfModule mod_expires.c>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|mp3|mp4|css|js|php)$">
ExpiresActive On
Header set Expires "Thu, 18 Jan 2012 20:00:00 GMT"
</FilesMatch>
</IfModule>
It works. This implies 2 things:
mod_expire is installed (IfModule mod_expires.c is true)
the Expire header is not modified after this rule is applied.
What am I missing?
By the way: if you have any solution to make it work I'm your man!
Ok I've got it from the official documentation here:
Note that if you use a modification date based setting, the Expires
header will not be added to content that does not come from a file on
disk. This is due to the fact that there is no modification time for
such content.
So it works only for static files, and not for all the other ones: they're not static.
This one got me stumped as well because AFAIK, it should work so I tried it on a test VM varying the N days and refreshing. Works fine for me. My Apache version is
Server version: Apache/2.2.14 (Ubuntu)
Server built: Nov 18 2010 21:17:19
Any the headers for a test file (using chrome developer tools) (with N=15) show:
Date:Mon, 09 Jan 2012 01:48:43 GMT
ETag:"7574-5-4b60e88a820a1"
Expires:Tue, 24 Jan 2012 01:48:43 GMT
My thought is that any ExpiresDefault can be overridden by a Header set Expires. Have you grepped the .htaccess hierarchy to make sure that your ExpiresDefault isn't being overridden at a lower level.
If you don't want htaccess files doing this you need to disable them in your http config.
I know that I can add expires header using mod_expires. However, what can I do if the Apache server doesn't have mod_expires installed and I don't want to route the access to the files through a scripting language like PHP?
You could use mod_header to set the header field manually:
Header set Expires "..."
But since Expires requires an absolute time, use Cache-Control’s max-age parameter for times relative to the access time:
Header merge Cache-Control max-age=3600
If you have static Expires headers, the following will add an Expires header to your js and css files:
<FilesMatch "\.(js|css)$">
Header set Expires "Fri, 01 Jan 2010 00:00:00 GMT"
</FilesMatch>
This should tell the browser to refresh the page on subsequent visits. The expires date just has to be in the past... you could set the date using PHP to make it "just" in the past, or just leave it as the date you found this answer!!!
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Thu, 2 Sep 2010 05:00:00 GMT");
UPDATE: Apologies - I missed the "Don't" in the sentence about routing files through PHP! You can also use these HTML meta tags:
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="expires" content="Thu, 2 Sep 2010 05:00:00 GMT">
I need to minimize Apache HTTP response headers, by now i reduced them as following
HTTP/1.1 200 OK
Date: Thu, 25 Mar 2010 21:57:41 GMT
Server: Apache
Content-Type: text/html
I'd like to know if there is a way to disable Date and Server header, only for a certain virtual host.
Thank you!
The Date header is required at part of the HTTP standard. You can't remove it without being non-compliant with the http standard, so apache doesn't generally allow that.