Nginx:替代内部位置块来caching基于variables的头部

我正在尝试使用Nginx页面caching而不是Wordpresscaching。 caching似乎工作正常,但我很难设置基于variables的条件caching头 – 无论用户是否login到WordPress。 如果用户login,我希望不应用高速caching头,如果不是,则可以通过Wordpress和CDN将页面高速caching一天。 我发现我只能在if语句中添加一个头文件。

我已阅读(但没有完全理解,因为这里迟了)[如果是邪恶的] [1]。 我也发现了一个堆栈交换(在我的笔记本电脑上,现在找不到它)的答案,在一个if块中只有一个add_header工作。

任何人都可以给我一个替代scheme的想法,可能会更好吗? 我知道我可以将失效与caching控制结合起来,但是我想要更多的头文件,再加上我想了解和学习。

这里有相关部分的一个显着简化的configuration。

server { server_name example.com; 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 uris containing the following segments. if ($request_uri ~* "/wp-admin/|/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; } location / { try_files $uri $uri/ /blog/index.php?args; } location ~ \.(hh|php)$ { fastcgi_keep_conn on; fastcgi_intercept_errors on; fastcgi_pass php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # Cache Stuff fastcgi_cache CACHE_NAME; fastcgi_cache_valid 200 1440m; add_header X-Cache $upstream_cache_status; fastcgi_cache_methods GET HEAD; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; add_header Z_ABCD "Test header"; if ($skip_cache = 1) { add_header Cache-Control "private, no-cache, no-store"; add_header CACHE_STATUS "CACHE NOT USED"; } if ($skip_cache = 0) { add_header Cache-Control "public, s-maxage = 240"; expires 1d; add_header CACHE_STATUS "USED CACHE"; } add_header ANOTHER_HEADER "message"; } } 

if指令的替代方法是map指令。 假设CACHE_STATUS vs CACHE_STATIC在你的问题中只是一个错字,你可以试试这个:

 map $http_cookie $expires { default 1d; ~*wordpress_logged_in off; } map $http_cookie $control { default "public, s-maxage = 240"; ~*wordpress_logged_in "private, no-cache, no-store"; } map $http_cookie $status { default "USED CACHE"; ~*wordpress_logged_in "CACHE NOT USED"; } server { ... location ~ \.(hh|php)$ { ... expires $expires; add_header Cache-Control $control; add_header CACHE_STATUS $status; } } 

map指令应该放在http容器内(与server块相同的级别),如上所示。

map指令在这里logging 。

我自己想出了一个解决scheme,根据理查德·史密斯提供的答案,并不是我所需要的。 我已经使用了更多的caching控制头,而是放弃了不必要的expires指令。

这位于服务器块内部

 if ($skip_cache = 1) { set $cacheControl "private, max-age=0, s-maxage=0, no-cache, no-store"; } if ($skip_cache = 0) { set $cacheControl "public, max-age=86400, s-maxage=86400"; } 

然后它进入每个适用的位置块

 add_header Cache-Control $cacheControl; 

这意味着位置块内不需要“如果”。 我认为这解决了这个问题,但是如果有人有其他想法,我仍然感兴趣。