I have a headers/cache issue in my lamp [centos] website.
Config:
[root@localhost httpd]# httpd -v
Server version: Apache/2.2.23 (Unix)
Server built: Nov 25 2012 15:03:00
[root@localhost httpd]# php -v
PHP 5.5.22 (cli) (built: Feb 20 2015 04:04:46)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2015, by Zend Technologies
php.ini:
session.cache_limiter = public
session.cache_expire = 535680
httpd.conf:
<IfModule mod_expires.c>
# enable expirations
ExpiresActive On
<FilesMatch "\.(php)$">
ExpiresDefault "access plus 1 month"
Header set Cache-Control "max-age=32140800, public"
Header unset ETag
Header unset Last-Modified
FileETag None
</FilesMatch>
</IfModule>
Meta tags:
<meta HTTP-EQUIV="cache-control" CONTENT="public, max-age=32140800">
The Issue:
- Load the page for the first time (named si.php here)
-
Clean access_log:
[root@localhost httpd]# > access_log
-
Press F5 in firefox/chrome:
[root@localhost httpd]# cat access_log 192.168.0.16 - user [25/Jun/2015:04:16:19 +0100] "GET /path/si.php HTTP/1.1" 200 642 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36"
-
Observe Http headers with live http headers firefox extension:
http://192.168.0.249/path/si.php GET /path/si.php HTTP/1.1 Host: 192.168.0.249 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate DNT: 1 Cookie: __utma=254085576.10126650.1407082841.1422764987.1429480306.10; __utmz=254085576.1407082841.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); PHPSESSID=1cuf6d8764vu2i2u1hin4pg665 Authorization: Basic cmVjZqR0ZTq1c2VyMQ== Connection: keep-alive Cache-Control: max-age=0 HTTP/1.1 200 OK Date: Thu, 25 Jun 2015 03:18:04 GMT Server: Apache X-Powered-By: PHP/5.5.22 Expires: Fri, 01 Jul 2016 03:18:04 GMT Cache-Control: max-age=32140800, public Vary: Accept-Encoding,User-Agent Content-Encoding: gzip Content-Length: 643 Keep-Alive: timeout=15, max=13 Connection: Keep-Alive Content-Type: text/html; charset=utf-8
Why on earth is the max-age=0 header sent? Firefox and Chrome display both the same behavior. This is an extra 170ms I currently cannot afford.
What is even weirder is the 200 http response code. I don't modify the page at all, it should at the very least return a 304…
Edit:
Ok, as accepted answer proposes, solution is to:
- not open a fresh browser (might not retrieve from cache)
- not pressing f5
- not just pressing enter in address bar
After the page has been visited a first time in this browser instance, any subsequent normal visit will be from cache:
Best Answer
When you hit F5 in a browser, you are instructing the browser to ask the sever and any proxies in the path for new content. That Cache-Control request header does just that. It does not get added during normal navigation.
Also, PHP has no way of knowing that your content didn't change, especially if it is making a database call. It will never return a 304 for a request unless you add code that makes it do so under whatever conditions. The reason you set a cache-control response header is so the browser won't even make a request at all if the resource is in cache.
Stop hitting F5, browse normally, and watch the traffic with Fiddler or similar tool. You'll find that when you visit your PHP page, then go somewhere else, then come back without hitting F5 that your browser shows your PHP page without even requesting it from the server at all. You're changing that normal caching behavior by hitting F5!