我已经完成了一个可以提供许多文档的小型PHP应用程序。这些文档必须可由客户和代理缓存。
由于代理可以缓存我的结果,我必须格外小心,因为我提供的文档可以有不同的MIME类型(基于$ _SERVER ['HTTP_ACCEPT']的内容协商)和不同的语言(基于以下顺序:$ _POST value / $ _GET值/ URL / PHP会话值/ $ _COOKIE值/ $ _SERVER ['HTTP_ACCEPT_LANGUAGE'] /默认脚本值)。
总而言之,一个页面可以使用相同的多种MIME 和多种语言提供服务(问题已更改:请参阅下面的编辑)。
为了帮助缓存代理,我使用“变化:接受”标题组合与ETag标头。 ETags是当前语言的MD5和最后修改的时间戳。
我总是:
现在提出我的问题:这是否足以帮助缓存代理和客户端?我错过了一个东西/标题吗?
为了帮助您,这是测试页面的HTTP响应标头(在我的本地环境中):
"
Date Wed, 30 Dec 2009 18:56:26 GMT
Server Apache/2.0.63 (Win32) PHP/5.1.0
X-Powered-By PHP/5.1.0
Set-Cookie Tests=697daqbmple2e1daq2dg74ur96; path=/
Expires Wed, 30 Dec 2009 21:56:26 GMT
Cache-Control public, max-age=10800
Last-Modified Mon, 28 Dec 2009 15:11:49 GMT
Etag "44fa50be4638161a596e4b75d6ab7a94"
Vary Accept
Content-Language en-us
Content-Length 3043
Keep-Alive timeout=15, max=100
Connection Keep-Alive
Content-Type application/xhtml+xml; charset=UTF-8
"
编辑:好的,我知道在这种情况下,提供一个包含许多MIME 和的文档(可能来自很多来源 - 见上文)只是简单的糟糕设计。如果你想这样做只需使用“私人”缓存(代理上没有缓存)......我是否正确?
如果每种语言都有自己的URL(但每个URL仍然可以提供许多MIME),那么我的当前实现是否可以用于“公共”缓存(客户端+代理上的缓存)?
答案 0 :(得分:3)
由于您的输出还取决于代理无法知道会话数据的内容,因此将(不可缓存的)重定向发送到实际内容不会更容易,这对于给定的URL(带参数)将是固定的因此更容易缓存。我知道这涉及额外的往返,但它可能更不容易出错,并且对于不完全理解/支持所有标题组合的代理也会导致更少的问题。
此外,我猜测,如果您有两个客户端通过相同的代理但使用不同的语言cookie,您当前的方法将为同一个URL返回两个不同的ETag,这将使代理每次更新其副本它看到了另一个客户。
答案 1 :(得分:1)
我相信你原则上应该没问题 - 添加Vary标头意味着缓存应该包含数据的多个实例,由ETag键入。
但我会注意到,您不仅在接受方面有所不同,而且您在Cookie和Accept-Language方面也有所不同。通过cookie改变意味着代理必须验证每个请求,但是应该能够使用If-None-Match标头让服务器指示应该使用哪个(已经缓存的)ETag。
答案 2 :(得分:0)
如果响应在“Accept”和“Accept-Language”上都有所不同,那么两者都需要在“Vary”响应标题中提及。