WooCommerce

SiteGround Optimizer文件缓存规则

SiteGround Optimizer可以在任何服务器上使用,最近的版本增加了文件缓存(File-Based Caching),可以在服务器上生成静态文件,后台可以设置的排除规则有两个:排除url或排除post type。这两个不够用,如果想根据cookie或url参数来排除怎么办?

禁用缓存包含两方面:

  1. 当条件符合时,不要给这次请求提供缓存的页面。
  2. 当条件符合时,不要用这次请求的内容生成缓存文件。

下面讨论一下根据cookie和url的参数来禁用缓存的方法。

SG Optimizer缓存配置文件

wp-content目录下有一个sgo-config.php文件,文件大体结构如下:

$config = array (
  'ignored_query_params' => 
  array (
    0 => 'fbclid',
    1 => 'fb_action_ids',
    ...
  ),
  'bypass_query_params' => 
  array (
  ),
  'bypass_cookies' => 
  array (
    0 => 'woocommerce_items_in_cart',
    1 => 'edd_items_in_cart',
    2 => 'wordpress_logged_in_',
    3 => 'wpSGCacheBypass',
    4 => 'comment_author_',
  ),
  'output_dir' => '',
  'logged_in_cache' => 0,
  'cache_secret_key' => '',
  'logged_in_cookie' => '',
);

该文件包含了缓存规则和缓存存放路径等配置信息,但我们不能直接修改这个文件,因为当插件禁用\开启缓存或清空缓存时,这个文件都会被重新生成。

但这个文件的内容会根据你的配置生成,从内容里可以看到主要能配置三个东西:

  • ignored_query_params:当请求带有指定参数时,不提供缓存的页面,也不会生成缓存。
  • bypass_cookies:当请求带有指定cookie时,不提供缓存的页面,也不会生成缓存。
  • bypass_query_params:暂时没发现有用。

当请求含有某个cookie时,禁用缓存

用插件WBW Currency Switcher for WooCommerce举个例子,这个插件允许切换多货币,考虑一下这个场景:

  1. 网站上有一个货币切换器,当货币切换时,产品价格也会发生变化,默认货币是USD。
  2. 缓存失效,需要重新生成缓存,用户A正好将货币切换到英镑,结果页面被缓存下来,价格是以英镑展示的。
  3. 用户B第一次访问网站,服务器发送了缓存页面,价格是英镑,但该用户在美国。
  4. 用户B将货币切换到美元,再点击其它页面,结果看到的还是英镑,因为这些都是缓存结果。

这样,不但能看到什么货币无法确定,不登陆时连切换货币的功能都会出问题。所以,我们首先要禁止向切换了语言的用户提供缓存页面,方法如下:

add_filter( 'sgo_bypass_cookies', function( $cookies ){
	$cookies[] = 'wcu_current_currency';
	return $cookies;
});

wcu_current_currency是多货币插件使用的cookie,有这个cookie说明用户已经切换过语言。但我们还要禁止用非默认货币生成缓存页面。

当请求URL包含某个参数时,禁用缓存

切换语言时,用户要访问带有特定参数的地址,例如https://yoursite.com/?currency=JPY。如果不排除currency这个参数,则访问这个地址时可能生成缓存,货币就不是默认的USD里。排除的方法如下:

add_filter( 'sgo_ignored_query_params', function( $params ){
	$params[] = 'currency';
	return $params;
});

这样,sg optimizer就会忽略这种类型的地址,不会用这种页面生成缓存文件。

注意

该插件生成缓存文件的过程有写bug,如下:

  • 只要url里带参数,不管什么参数,都不生成缓存文件。
  • 通过filter增加的cookie不会影响缓存生成过程,无法通过cookie来禁止生成缓存,这是代码结构的问题。

通过修改插件代码可以解决此问题,但还是等插件作者更新吧。

留言

您的电子邮箱地址不会被公开。