max-age=0 sent by browsers despite headers modified everywhere

5,556

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!

Share:
5,556

Related videos on Youtube

Sebas
Author by

Sebas

Cloud Architect and Solution Architect @ different multinationals

Updated on September 18, 2022

Comments

  • Sebas
    Sebas over 1 year

    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:

    1. Load the page for the first time (named si.php here)
    2. Clean access_log:

      [root@localhost httpd]# > access_log
      
    3. 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"
      
    4. 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:

    1. not open a fresh browser (might not retrieve from cache)
    2. not pressing f5
    3. 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:

    enter image description here

  • Sebas
    Sebas almost 9 years
    You are right. Pasting the url from another page displays (from cache) in the chrome console... You know, I had read something about that. A guy suggested to just press enter in the url instead of pressing f5, to prevent that behavior, but it didn't work for me so I had left that aside. But this time I just tried to browse "normally" and it worked.