php - Varnish 不适用于WooCommerce

标签 php wordpress woocommerce varnish

我们正在尝试将Varnish添加到我们的Woocommerce设置中,并且遇到了一些麻烦。

在产品页面上(例如说/product/television),如果您按“添加到购物车”按钮,则可以按预期将您重定向到购物车页面,但尚未将商品添加到购物车中。
但是,如果您在登录帐户时执行相同的操作,它将可以正常工作。我已经在下面发布了我的varnish.vcl,如果任何人对错误之处有任何见解,请告诉我。

    # This is an example VCL file for Wordpress/WooCommerce/Varnish.
    #

    # Updated to work with Varnish 4


    # Marker to tell the VCL compiler that this VCL has been adapted to the
    # new 4.0 format.
    vcl 4.0;

    # Default backend definition. Set this to point to your content server.
    backend default {
        .host = "web";
        .port = "80";
        .connect_timeout = 600s;
        .first_byte_timeout = 600s;
        .between_bytes_timeout = 600s;
        .max_connections = 800;
    }

    # Only allow purging from specific IPs
    acl purge {
        "localhost";
    }

    # This function is used when a request is send by a HTTP client (Browser) 
    sub vcl_recv {
        # Normalize the header, remove the port (in case you're testing this on various TCP ports)
        set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");

        # The code below makes sure the AJAX "add to cart" function works
        set req.url = regsub(req.url, "add-to-cart=\d+_\d+&", "");

        # Allow purging from ACL
        if (req.method == "PURGE") {
            # If not allowed then a error 405 is returned
            if (!client.ip ~ purge) {
                return(synth(405, "This IP is not allowed to send PURGE requests."));
            }   
            # If allowed, do a cache_lookup -> vlc_hit() or vlc_miss()
            return (purge);
        }

        # Post requests will not be cached
        if (req.http.Authorization || req.method == "POST") {
            return (pass);
        }

        # --- Wordpress specific configuration

        # Did not cache the RSS feed
        if (req.url ~ "/feed") {
            return (pass);
        }

        # Blitz hack
            if (req.url ~ "/mu-.*") {
                    return (pass);
            }


        # Do not cache the admin and login pages
        if (req.url ~ "/wp-(login|admin)") {
            return (pass);
        }

        # Do not cache the WooCommerce pages

        if (req.url ~ "/(cart|my-account|checkout|addons)") {
            return (pass);
        }

        if (req.url ~ "/?add-to-cart=") {
            return (pass);
        }

        # Remove the "has_js" cookie
        set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");

        # Remove any Google Analytics based cookies
        set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");

        # Remove the Quant Capital cookies (added by some plugin, all __qca)
        set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");

        # Remove the wp-settings-1 cookie
        set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");

        # Remove the wp-settings-time-1 cookie
        set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");

        # Remove the wp test cookie
        set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");

        # Are there cookies left with only spaces or that are empty?
        if (req.http.cookie ~ "^ *$") {
                unset req.http.cookie;
        }

        # Cache the following files extensions 
        if (req.url ~ "\.(css|js|png|gif|jp(e)?g|swf|ico)") {
            unset req.http.cookie;
        }

        # Normalize Accept-Encoding header and compression
        # https://www.varnish-cache.org/docs/3.0/tutorial/vary.html
        if (req.http.Accept-Encoding) {
            # Do no compress compressed files...
            if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
                    unset req.http.Accept-Encoding;
            } elsif (req.http.Accept-Encoding ~ "gzip") {
                    set req.http.Accept-Encoding = "gzip";
            } elsif (req.http.Accept-Encoding ~ "deflate") {
                    set req.http.Accept-Encoding = "deflate";
            } else {
                unset req.http.Accept-Encoding;
            }
        }

        # Check the cookies for wordpress-specific items
        if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {
            return (pass);
        }
        if (!req.http.cookie) {
            unset req.http.cookie;
        }

        # --- End of Wordpress specific configuration

        # Did not cache HTTP authentication and HTTP Cookie
        if (req.http.Authorization || req.http.Cookie) {
            # Not cacheable by default
            return (pass);
        }

        # Cache all others requests
        return (hash);
    }

    sub vcl_pipe {
        return (pipe);
    }

    sub vcl_pass {
        return (fetch);
    }

    # The data on which the hashing will take place
    sub vcl_hash {
        hash_data(req.url);
        if (req.http.host) {
            hash_data(req.http.host);
        } else {
            hash_data(server.ip);
        }

        # If the client supports compression, keep that in a different cache
            if (req.http.Accept-Encoding) {
                hash_data(req.http.Accept-Encoding);
        }

        return (lookup);
    }

    # This function is used when a request is sent by our backend (Nginx server)
    sub vcl_backend_response {
        # Remove some headers we never want to see
        unset beresp.http.Server;
        unset beresp.http.X-Powered-By;

        # For static content strip all backend cookies
        if (bereq.url ~ "\.(css|js|png|gif|jp(e?)g)|swf|ico") {
            unset beresp.http.cookie;
        }

        # Only allow cookies to be set if we're in admin area
        if (beresp.http.Set-Cookie && bereq.url !~ "^/wp-(login|admin)") {
                unset beresp.http.Set-Cookie;
            }

        # don't cache response to posted requests or those with basic auth
        if ( bereq.method == "POST" || bereq.http.Authorization ) {
                set beresp.uncacheable = true;
            set beresp.ttl = 120s;
            return (deliver);
            }

            # don't cache search results
        if ( bereq.url ~ "\?s=" ){
            set beresp.uncacheable = true;
                    set beresp.ttl = 120s;
                    return (deliver);
        }

        # only cache status ok
        if ( beresp.status != 200 ) {
            set beresp.uncacheable = true;
                    set beresp.ttl = 120s;
                    return (deliver);
        }

        # A TTL of 24h
        set beresp.ttl = 24h;
        # Define the default grace period to serve cached content
        set beresp.grace = 30s;

        return (deliver);
    }

    # The routine when we deliver the HTTP request to the user
    # Last chance to modify headers that are sent to the client
    sub vcl_deliver {
        if (obj.hits > 0) { 
            set resp.http.X-Cache = "cached";
        } else {
            set resp.http.x-Cache = "uncached";
        }

        # Remove some headers: PHP version
        unset resp.http.X-Powered-By;

        # Remove some headers: Apache version & OS
        unset resp.http.Server;

        # Remove some heanders: Varnish
        unset resp.http.Via;
        unset resp.http.X-Varnish;

        return (deliver);
    }

    sub vcl_init {
        return (ok);
    }

    sub vcl_fini {
        return (ok);
    }

最佳答案

我在这里找到了解决此问题的方法:
https://guides.wp-bullet.com/fix-empty-cart-with-woocommerce-redirect-to-checkout-varnish-4/

基本上,当您将商品添加到购物车时,Woocommerce会发出302重定向并将您发送到购物车(您可以从设置中禁用此行为)。在Varnish中,必须确保在发生此事件时不要从后端响应中删除任何cookie。

sub vcl_backend_response {
   if (!(bereq.url ~ "wp-(login|admin)|cart|my-account|wc-api|resetpass") &&
    !bereq.http.cookie ~ "wordpress_logged_in|woocommerce_items_in_cart|resetpass" &&
    !beresp.status == 302 ) {
       unset beresp.http.set-cookie;
       set beresp.ttl = 1w;
       set beresp.grace = 1d;
   }
}

关于php - Varnish 不适用于WooCommerce,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34637119/

相关文章:

php - 防止产品页面中的可点击图片,禁用产品图片链接

ajax - Woocommerce Ajax 以编程方式添加到购物车

php - 无法选择数据库名称 - PHP mySQL 数据库查询 XML

php - mySqli 绑定(bind)参数 LIKE 与通配符

wordpress - 在注销前和管理员登录后设置 cookie

javascript - 如何在 href 中间添加变量?

php - 我的代码错误通知 : Trying to get property of non-object in

php - 在 GitHub 上使用 Composer 和 Private Repository 在 Build Server 上使用 VCS

php - 编辑 woocommerce 行总数

php - Woocommerce 添加具有外部/附属类型的产品