Bypass page cache created by W3 Total Cache

I’m using W3 Total cache plugin setting page cache using the APC module.
Thing is that since I’ve enabled the page cache cookies I was setting in my theme header stopped being set, also reading existing cookie and redirecting by it’s value stopped working as well.

I’m almost 100% sure it’s the page cache causing it and I’m unable to find a proper programmatic solution to intercept the page cache and set the required cookies, prior to W3TC page cache.
Also simple debugging shows the PHP script being read yet setCookie not setting the cookies.
Moreover, clearing the page cache via wordpress admin and purging varnish cache allows set of the cookies, though only once, since rest of the calls to the page would be cached (304 response).

Read More

I’ve consulted with the PHP manual regarding setcookie and made sure my cookie is set prior to any HTML/whitespaces

I’ve checked the .htaccess file and no page cache is set there, so overcoming this issue using PHP should be possible I assume.

I don’t want to disable the page cache and lose the server response time major improvement it offers.

Any ideas how to overcome this issue?

Related posts

Leave a Reply

2 comments

  1. This is most likely a Varnish issue. You may want to disable it from caching your cookies when you are accessing the back-end of your WP site, and purge Varnish’s cache after making modifications to your theme so that it will cache the new “view” of your site.

    I have used your W3TC + Varnish solution before and it takes a bit of tinkering to get it right. My tip for using Varnish for WP (part of the config) you can reference (and not copy):

    sub vcl_recv {
        # Don't cache WordPress backend
        if (req.url ~ "wp-(login|admin|comments-post.php|cron.php)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
            return (pass);
        }
    
        # Don't cache if WordPress cookie is present
        if (req.http.cookie) {
            if (req.http.cookie ~ "(wordpress_|wp-settings-)") {
                return(pass);
            } else {
                unset req.http.cookie;
            }
        }
    }
    
    sub vcl_fetch {
        # Don't cache WordPress backend
        if (req.url ~ "wp-(login|admin|comments-post.php|cron.php)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
            set beresp.http.magicmarker = "1";
            return (hit_for_pass);
        }
        if ( (!(req.url ~ "(wp-(login|admin|comments-post.php|cron.php)|login)")) || (req.request == "GET") ) {
            unset beresp.http.set-cookie;
            set beresp.ttl = 4h;
        }
    }
    

    Then also add in a PURGE block so that W3TC can purge the cache (instead of you doing it manually) after a site/theme update.

    acl purge {
        # Only allow the server to issue PURGE requests
        "127.0.0.1";
        "localhost";
        "162.243.151.227";
    }
    
    sub vcl_hit {
        if (req.request == "PURGE") {
            purge;
            error 200 "HIT Purged.";
        }
    }
    
    sub vcl_miss {
        if (req.request == "PURGE") {
            purge;
            error 200 "MISS Purged.";
        }
    }
    
    sub vcl_recv {
        # PURGE requests
        if (req.request == "PURGE") {
            if (!client.ip ~ purge) {
                error 401 "Not allowed.";
            }
            # 3 ways to refresh the cache:
            # 1: force lookup
            # return (lookup);
            # 2: url purging: http://wordpress.stackexchange.com/questions/76037/make-w3-total-cache-empty-all-caches-function-purge-varnish
            # purge_url(req.url);
            # 3: ban to invalidate cache content
            ban("req.url ~ ^" + req.url + "$ && req.http.host == " + req.http.host);
            error 200 "RECV Purged.";
            # Observe with: varnishlog -I 'VCL_error'
        }
    }
    
  2. I read “Varnish” in your post and have a little experience in that (although only from Drupal projects, not WP). Varnish i a reverse proxy that serve anonymous data. Cookies is not anonymous. Isn’t that a problem per se?

    Perhaps you could configured Varnish to ignore pages beeing cached with a specific cookie, but that would probably not help speeding up you webpage.

    When I need fast WP-sites I use hhvm + nginx, maybe that´s an alternative for you.

    And, yes, I know this is not an answer to your question, but im not sure there is a PHP solution as you state in your post given the server setup explained. I hope you can forgive me for that.