nginx缓存但使用`Cache-Control:public,s-maxage = 0`立即过期/重新验证

tlr*_*son 5 reverse-proxy nginx cache-control http-caching http-headers

我想使用HTTP代理(例如nginx)来缓存大量/昂贵的请求.这些资源对于任何授权用户都是相同的,但是每个请求的后端都需要检查其身份验证/授权.

这听起来像是Cache-Control: public, max-age=0与nginx指令proxy_cache_revalidate on;一起执行此操作的方式.代理可以缓存请求,但是每个后续请求都需要对后端执行条件GET,以确保在返回缓存资源之前对其进行授权.如果用户未经授权,则后端发送403,如果用户被授权则发送304,并且缓存的资源不是陈旧的,或者如果新资源已过期,则发送200.

在nginx max-age=0中设置了if ,根本不缓存请求.如果max-age=1设置,那么如果我在初始请求之后等待1秒,那么nginx会执行条件GET请求,但是在1秒之前它直接从缓存服务它,这对于需要进行身份验证的资源来说显然非常糟糕.

有没有办法让nginx缓存请求但是立即需要重新验证?

请注意,这在Apache 可以正常工作.以下是nginx和Apache的示例,前两个有max-age = 5,最后两个有max-age = 0:

# Apache with `Cache-Control: public, max-age=5`

$ while true; do curl -v http://localhost:4001/ >/dev/null 2>&1 | grep X-Cache; sleep 1; done
< X-Cache: MISS from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: HIT from 172.x.x.x

# nginx with `Cache-Control: public, max-age=5`

$ while true; do curl -v http://localhost:4000/ >/dev/null 2>&1 | grep X-Cache; sleep 1; done
< X-Cached: MISS
< X-Cached: HIT
< X-Cached: HIT
< X-Cached: HIT
< X-Cached: HIT
< X-Cached: HIT
< X-Cached: REVALIDATED
< X-Cached: HIT
< X-Cached: HIT

# Apache with `Cache-Control: public, max-age=0`
# THIS IS WHAT I WANT

$ while true; do curl -v http://localhost:4001/ >/dev/null 2>&1 | grep X-Cache; sleep 1; done
< X-Cache: MISS from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x

# nginx with `Cache-Control: public, max-age=0`

$ while true; do curl -v http://localhost:4000/ >/dev/null 2>&1 | grep X-Cache; sleep 1; done
< X-Cached: MISS
< X-Cached: MISS
< X-Cached: MISS
< X-Cached: MISS
< X-Cached: MISS
< X-Cached: MISS
Run Code Online (Sandbox Code Playgroud)

正如您在前两个示例中所看到的,Apache和nginx都可以缓存请求,并且Apache正确缓存了max-age = 0请求,但nginx却没有.

cns*_*nst 0

我认为你最好的选择是在X-Accel-Redirect.

\n\n

其功能默认启用,并在以下文档中进行了描述proxy_ignore_headers

\n\n
\n

\xe2\x80\x9cX-Accel-Redirect\xe2\x80\x9d 执行到指定 URI 的内部重定向;

\n
\n\n

然后,您可以缓存所述内部资源,并自动为任何已通过身份验证的用户返回该资源。

\n\n

由于重定向必须是internal,因此不会有任何其他方式可以访问它(例如,没有某种内部重定向),因此,根据您的要求,未经授权的用户将无法访问它,但它仍然可以像任何其他location.

\n