我正在使用Nginx作为缓存代理服务器。我在使用X-Accel-Expires和Cache-Control标头缓存响应时遇到问题。
我的上游返回一些带有标头的请求正文到nginx:
[...]
X-Accel-Expires: 60
Cache-Control: no-cache
[...]
我的意图是nginx将缓存响应60秒,但客户端将仅获得Cache-Control:no-cache标头(因此它们将不会在浏览器中缓存响应)。
但是nginx不会缓存该响应。Nginx使用Cache-Control标头,而忽略X-Accel-Expires标头。我以为X-Accel-Expires比Cache-Control “更强”,但事实并非如此。
有什么办法可以改变吗?
我知道我可以使用:
proxy_ignore_headers Cache-Control;
但是我不能这样做,因为在上游服务器的每个响应中都没有X-Accel-Expires标头。
总结一下,当我从上游返回thoose标头时:
X-Accel-Expires: 60
Cache-Control: no-cache
我想在nginx缓存中缓存响应60秒钟,但返回到客户端Cache-Control:no-cache。
但是当我返回这个:
Cache-Control: max-age=90
(没有X-Accel-Expires头)我想在nginx缓存中缓存响应60秒钟,然后返回到客户端Cache-Control:max-age = 90头。
这可能吗?
然后,
X-Accel-Expires
每次发送标头,或使用add_header
指令添加标头(例如$http_cache_control
,在if语句中使用)。Cache-Control
标题以进行每次缓存。map $upstream_http_cache_control $cache_control_value { "~^max-age=(?<duration>\d+)$" "$duration"; }
服务器 {
listen 127.0.0.1:80; upstream nodes { server foo; } location / { if ($upstream_http_x_accel_expires = '') { add_header "X-Accel-Expires" $cache_control_value; } proxy_set_header "Host" $host; proxy_pass http://nodes; }
}
服务器 {
server_name mydomain.com; listen X.X.X.X:80; upstream intermediate { server 127.0.0.1; } location / { proxy_set_header "Host" $host; proxy_pass http://intermediate; proxy_ignore_headers 'Cache-Control'; proxy_cache mycache; }
}
对于最后一种情况,请参考第一个点或use proxy_cache_valid
,但是使用最后一个参数,你将无法使超时动态化。你一次需要一些连贯的工作流程。
感谢您的回答,但这无法正常工作。在这种情况下,如果nginx缓存模块决定不缓存响应,则“ if”逻辑起作用。我的上游只返回了:Cache-Control:60。Nginx适当地添加了X-Accel-Expires头,但是缓存中没有文件,客户端在响应中看到了Cache-Control和X-Accel-Expires头。因此,很明显,此IF逻辑是在发生缓存逻辑之后放置的。
@Tereska当然,您需要设置一个中间虚拟主机。为清楚起见,请参阅更新的答案。但是请记住,实现此目标的最佳方法是更正您的工作流程。
哇。这很聪明:)还有一件事:Cache-Control:max-age = 60。如何仅将值“ 60”(没有maxage =)从Cache-Control放到X-Accel-Expires(我指的是IF语句)。没有一些regexp(?),我将得到X-Accel-Expires:max-age = 60(我认为这将不起作用(?))
@Tereska使用一条
map
语句并使用正则表达式捕获正确的值。你能举个例子吗?你是什么意思?(如果没有时间,它可能是伪代码)。谢谢你。