听起来像是使用
Cache-Control: public, max-age=0
以及nginx指令proxy_cache_revalidate on;
来实现这一点。代理可以缓存请求,但每个后续请求都需要进行条件GET到后端以确保经过授权后才返回缓存的资源。然后,如果用户未经授权,后端将发送403;如果用户经过授权且缓存的资源未过期,则发送304;如果资源已过期,则发送200和新资源。在nginx中,如果设置了
max-age=0
,则根本不会缓存该请求。如果设置了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
正如您在前两个示例中所看到的,Apache和nginx都能够缓存请求,而且Apache可以正确地缓存max-age = 0的请求,但是nginx不能。
X-Accel-Redirect
就是你要找的!祝你好运! - cnstX-Accel-Redirect
。缺点是每个前端请求需要向后端发送两个请求。优点是 Nginx 配置简单且可以拆分后端逻辑。 - Dmitry MiksIr