NginX没有考虑ETag

时间:2016-11-07 00:56:59

标签: php symfony caching nginx

我在NginX上启用了缓存(使用fastCGI)。

我的动态页面不会经常更改,我希望它们存储在NginX缓存中,只要它们没有更改(我知道,我可以创建静态页面......让我们说它们仍然是由于历史原因“动态”。

当我的后端服务器(Symfony 2)生成页面时,它会将ETAG + max-age参数添加到响应头。

我希望浏览器将页面保留在其缓存中一段时间​​。一旦这个时间到期,我希望浏览器使用提供的ETAG发送“If-None-Match”HTTP HEAD。

如果页面仍然存在于前端缓存中,我希望NginX发送304 Not Modified响应。

如果页面不再存在(如果更改,我会手动清除它)我希望NginX将请求转发到发送回HTTP 200响应的后端服务器。

没有fastCGI 缓存我可以看到etag参数出现在响应头(firefox的调试面板)中。但每次重新加载页面时,我都会看到HTTP 200响应,而不是HTTP 304响应。

使用fastCGI 缓存,ETag完全从最初的HTTP 200响应中消失。每次重新加载页面都会导致HTTP 200响应(尽管X-Fastcgi-Cache参数告诉我这是一个HIT)

我的问题

为什么浏览器发送GET请求而不是HEAD请求虽然存在ETag?

为什么在NginX上启用fastCGI缓存时,ETag会从响应中消失?

我对缓存很陌生,所以我可能会遗漏一些大事......

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

经过调查,这些问题的原因是Firefox将ETag设置为“弱”"当以压缩格式接收页面时。它通过添加额外的" W /"在ETag字符串之前。

这导致symfony无法识别ETag与先前发送的ETag相同,因此HTTP 200响应而不是HTTP 304。

这个额外弱信息背后的原因似乎是,在数据被压缩之前计算ETag时,它可能导致ETag值冲突,从而导致页面卡在缓存中,而应该更新。为了防止这个Firefox(以及NginX获取信息)添加弱(ness)信息。

希望这可以帮助有同样问题的人......