Назад | Перейти на главную страницу

Nginx - отключить агрессивное кеширование для админки Wordpress

У меня сейчас полностью установлен Nginx с PHP-FPM. Исходя из мира Apache с проксированием Nginx впереди.

Похоже, у Nginx есть свое капризное кеширование, очень агрессивное. Есть несколько уровней кеширования:

  1. Сам кеш Fastcgi Nginx. В моем 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;
    }
    

Несмотря на все это, мои административные экраны настолько агрессивно кэшированы, что когда я активирую плагин, он показывает старый экран. Когда плагин был деактивирован. Только когда я вручную обновляю страницу, я вижу, что плагин действительно активирован.

Что мне не хватает?

Эта конфигурация выглядит знакомой. Я думаю, это, вероятно, взято из вики WordPress. В любом случае это слишком сложно и в основном ненужно.

Я собираюсь получить свою конфигурацию с живого сайта 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.

Способ, предложенный @MichaelHampton, IMHO лучший (самый простой, самый эффективный), но вот альтернативный / дополнительный подход, который может быть полезен в некоторых ситуациях. Это исходит от моего Wordpress / Nginx учебник. Некоторые темы очень плохо связаны с кешированием заголовков, поэтому я в основном хочу переписать все заголовки по-разному для разных областей веб-сайта. Я также удаляю старый заголовок Pragma.

Я определяю блоки для определенных URL-адресов или подкаталогов, чтобы я мог более точно оценивать ограничение или контролировать заголовки.

Обратите внимание, что more_clear_headers и add_header являются частью Заголовки Подробнее Расширение 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;
}

Чтобы добавить что-то еще к ответу Майкла, я также использую этот блок. Он отключает кеширование для Wordpress Admin вторым способом, а также отключает кеширование для каналов, карты сайта, xmlrpc и некоторых других. Частично это для Wordpress, я подозреваю, что частично для написанного на заказ веб-сайта PHP, который я запускаю.

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