Nginx——禁用 Wordpress 管理区域的积极缓存

Nginx——禁用 Wordpress 管理区域的积极缓存

我现在已经安装好了 Nginx,并安装了 PHP-FPM。我来自一个使用 Nginx 代理的 Apache 世界。

看来 Nginx 有自己的喜怒无常的缓存,非常激进。缓存有几层:

  1. Nginx 的 fastcgi 缓存本身。在我的 nginx.conf 中,我有以下设置:

    fastcgi_cache_path        /var/run/nginx-cache  levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
    fastcgi_cache_key         "$scheme$request_method$host$request_uri";
    fastcgi_cache_use_stale   error timeout invalid_header http_500;
    fastcgi_ignore_headers    Cache-Control Expires Set-Cookie;
    
  2. 然后是 php opcache。我暂时禁用了它:

    ;zend_extension=opcache.so
    opcache.enable=0
    opcache.enable_cli=0
    opcache.memory_consumption=250
    opcache.interned_strings_buffer=8
    opcache.max_accelerated_files=6000
    opcache.revalidate_freq=600
    opcache.fast_shutdown=1
    
  3. 我在服务器块中还包含以下跳过缓存指令:

    set $skip_cache 0;
    
    # POST requests and urls with a query string should always go to PHP
    if ($request_method = POST) {
            set $skip_cache 1;
    }
    if ($query_string != "") {
            set $skip_cache 1;
    }
    
    #Don't cache the following URLs
    if ($request_uri ~* "/(wp-login.php|wp-admin|login.php|backend|admin)"){
        set $skip_cache 1;
    }
    
    #Don't cache if there is a cookie called PHPSESSID
    if ($http_cookie ~* "PHPSESSID"){
        set $skip_cache 1;
    }
    
    #Don't cache if there is a cookie called wordpress_logged_in_[hash]
    if ($http_cookie ~* "wordpress_logged_in_"){
        set $skip_cache 1;
    }
    
    # Don't cache uris containing the following segments
    if ($request_uri ~* "cms/|/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
            set $skip_cache 1;
    }
    
    # For the arc 
    if ($request_uri ~* "site/|/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
            set $skip_cache 1;
    }
    
    # Don't use the cache for logged in users or recent commenters
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
            set $skip_cache 1;
    }
    
  4. 然后在 PHP 块中,我使用 skip_cache 内容:

    location ~ \.php$ {
    
          try_files $uri $uri/ =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
    
            fastcgi_cache_bypass                $skip_cache;
          fastcgi_no_cache                    $skip_cache;
            fastcgi_cache                       WORDPRESS;
            fastcgi_cache_valid  200 301 302    60m;
    }
    

尽管如此,我的管理屏幕缓存得如此之多,以至于当我激活插件时,它会显示旧屏幕。当插件被停用时。只有当我手动刷新页面时,我才能看到插件确实已激活。

我错过了什么?

答案1

@MichaelHampton 建议的方法在我看来是最好的(最简单、最有效),但这里有一个在某些情况下可能有用的替代/附加方法。它来自我的Wordpress / Nginx 教程。有些主题会以非常糟糕的方式干扰缓存标头,因此我基本上想针对网站的不同区域以不同的方式重写所有标头。我还删除了旧的 Pragma 标头。

我为特定的 URL 或子目录定义了块,以便可以更精确地限制速率或控制标题。

请注意,“more_clear_headers”和“add_header”是Headers 更多 Nginx 扩展。如果您查看我上面链接的教程第二部分,它会逐步说明如何使用该模块构建 Nginx - 这非常简单。

# Rate limiting for login pages
limit_req_zone $binary_remote_addr zone=login:1m rate=5r/m;

# Rate limit wp-login.php to help prevent brute force attacks
location = /blog/wp-login.php {
  # Next line applies the rate limit defined above
  limit_req zone=login burst=3;       
  fastcgi_keep_conn on;
  fastcgi_intercept_errors on;
  fastcgi_pass   php;
  include        fastcgi_params;
  fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
  more_clear_headers "Cache-Control";
  more_clear_headers Server; more_clear_headers "Pragma"; more_clear_headers "Expires";

  # No caching
  more_clear_headers "Cache-Control";
  add_header Cache-Control "private, max-age=0, no-cache, no-store";
  more_clear_headers "Expires";

  # Debugging aid - remove
  # add_header Z_LOCATION "WP-LOGIN"; add_header URI $uri;
}

# Wordpress admin caching headers are generally set correctly, for pages and resources. The only reason we define
# this block separately is to avoid messing with the headers in the main php block.
# This is probably unnecessary because of the skip_cache variable and may be removed
location ~* wp-admin {
  fastcgi_keep_conn on;
  fastcgi_intercept_errors on;
  fastcgi_pass   php;
  include        fastcgi_params;
  fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;

  # Debugging aid - remove
  # add_header Z_LOCATION "WP_ADMIN"; add_header URI $uri; add_header "Z_SKIP_CACHE" $skip_cache;
}

为了补充 Michael 的回答,我还使用了这个块。它以第二种方式禁用了 Wordpress Admin 的缓存,还禁用了 feed、sitemap、xmlrpc 和其他一些缓存。部分是用于 Wordpress,我怀疑部分是用于我运行的自定义 PHP 网站。

if ($request_uri ~* "/wp-admin/|/admin-*|/purge*|/xmlrpc.php|wp-.*.php|/feed/|sitemap(_index)?.xml|wp-cron") {
  set $fastcgi_nocache "true";
}   

答案2

这段配置看起来很熟悉。我想它可能来自 WordPress wiki。无论如何,它太复杂了,而且大多没有必要。

我将从实时 WordPress 网站中提取我的配置:

set $fastcgi_nocache "";
if ($http_cookie ~ (comment_author_.*|wordpress_logged_in.*|wp-postpass_.*)) {
    set $fastcgi_nocache "true";
}
fastcgi_ignore_headers Expires Cache-Control;
fastcgi_hide_header Pragma;
fastcgi_cache_bypass $fastcgi_nocache;
fastcgi_no_cache $fastcgi_nocache;

就这些。您真正需要检查的唯一一件事是用户是否有一个 cookie 表明他已登录、是否留下了评论并希望被记住,或者是否输入了帖子密码。其他一切都无关紧要或不适用于 WordPress。

答案3

几个月来我都遇到同样的问题...尝试了许多不同的 Nginx 配置...但都没有用。

问题:

  • 管理后端已被缓存,因此在创建新页面或安装插件时不会更新。
  • 在前端和后端之间切换,甚至单击链接时都会重定向以重新进行授权。

只是一个简单的问题:CLOUDFLARE

我的页面规则如下:

*.mysite.com/* - Cache Level: Cache Everything

我删除了该规则,清除了缓存,现在一切恢复正常。

相关内容