Mik*_*nen 12 proxy history caching http browser-cache
我正在尝试找出最好的HTTP标头,以便为四个用例发送.我希望得到不依赖于用户代理/协议版本嗅探的标题,但我会接受,如果没有别的东西适合.所有URL都是通过完全自定义处理程序获取的,因此我可以根据需要选择所有标头,这完全是关于中间代理和用户代理.如果可能,这应该与HTTP/1.0和HTTP/1.1客户端兼容.如果存在多个解决方案,则最好的解决方案将是通过线路发送的最短解决方案.
静态公共内容
所有"静态公共内容"都是HTTP真正关注的东西:如果URL相同,则内容是相同的.我可以轻松地做到这一点:例如,我将用户个人资料图标放入http://domain.com/profiles/xyz/icon/1234abcd,其中"1234abcd"是图标文件内容的SHA-1.如果我将来更改为图标,我将创建一个新URL并修改应使用新图标的所有现有引用.什么是最好的标头声明这可以永久缓存并可以共享?我正在考虑一些事情:
Date: <current time>
Expires: <current time + one year>
Run Code Online (Sandbox Code Playgroud)
这是否足以允许用户代理和代理进行缓存?我需要Last-Modified还是Pragma?
静态非公开内容
所有"静态非公开内容"都是静态的,但并非每个人都可以使用.实际上,此内容仅对选定的登录用户可用(会话保持会话cookie保持会话UUID).如果URL相同,则内容相同.但是,回应不公开.用例可以是在社交网络服务中与所选朋友共享的图像.我正在考虑一些事情:
Date: <current time>
Expires: <current time>
Cache-Control: private, max-age=<huge number>, s-maxage=0
Run Code Online (Sandbox Code Playgroud)
这是否足以允许用户代理缓存并禁用代理?我需要Pragma吗?
不稳定的公共内容
所有"易变的公共内容"都是易变的东西,可供所有人使用.当没有登录时,有点像http://slashdot.org/的首页.目的是允许在不变的URL中快速更新内容.请注意,我不想破坏用户代理历史记录机制(即,从易失性页面单击某些内容然后点击后退按钮不应导致从服务器获取易失性页面 - 但是,单击指向该服务器的链接首页应该从服务器获取资源).我正在考虑一些事情:
Date: <current time>
Expires: <current time>
Cache-Control: public, max-age=0, s-maxage=0
Run Code Online (Sandbox Code Playgroud)
这是否足以阻止缓存但允许历史记录机制(后退按钮)?我知道,如果我发送,Cache-Control: no-store, must-revalidate我可以强制重装,但这不是我想要的,因为这也会打破后退按钮.我需要Last-Modified还是Pragma?
尽管这是公开的,但允许中间代理缓存它可能没有意义,因为它是不稳定的.
不稳定的非公开内容
所有"易变的非公开内容"都是易变的东西,并不是每个人(私人)都可以使用.当你登录时,有点像http://slashdot.org/的首页.目的是允许在不变的URL中快速更新内容.请注意,我不想破坏用户代理历史记录机制(即,从易失性页面单击某些内容然后点击后退按钮不应导致从服务器获取易失性页面 - 但是,单击指向该服务器的链接首页应该从服务器获取资源).我正在考虑一些事情:
Date: <current time>
Expires: <current time>
Cache-Control: private, max-age=0, s-maxage=0
Run Code Online (Sandbox Code Playgroud)
这是否足以阻止缓存但允许历史记录机制(后退按钮)?我需要Pragma吗?
仍需要使用我建议的标题进行测试的事情:
Mik*_*nen 10
我会回答我自己的问题:
静态公共内容
Date: <current time>
Expires: <current time + one year>
Run Code Online (Sandbox Code Playgroud)
理由:这是与HTTP/1.0代理和RFC 2616兼容第14节:http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21
的Last-Modified不需要用于正确的缓存头(因为符合要求的用户代理遵循Expires标题)但可以包括在最终用户消费中.Last-Modified如果用户点击"重新加载/刷新"按钮,则包括标题也可能会减少服务器数据传输.如果Last-Modified添加了标题,它应该反映真实数据而不是发明的东西.如果您想减少服务器数据传输(如果用户点击重新加载/刷新按钮)并且不能包含真实Last-Modified标题,您可以添加ETag标题以允许条件GET(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14 .html#sec14.26).如果你已经Last-Modified加入ETag也只是浪费.请注意,这Last-Modified显然是优越的,因为它也受HTTP/1.0客户端和代理的支持.ETag在动态页面的情况下,合适的值是页面/资源的内容的SHA-1.请注意,使用Last-Modified或ETag无助于服务器加载,仅使用服务器传出的Internet管道/数据传输速率.
静态非公开内容
Date: <current time>
Expires: <current time>
Cache-Control: private, max-age=31536000, s-maxage=0
Vary: Cookie
Run Code Online (Sandbox Code Playgroud)
基本原理:Date和Expires标头用于HTTP/1.0兼容性,并且由于没有明智的方法来指定响应是私有的,因此这些标头表示响应可能未被缓存.该Cache-Control头告诉这个反应可能是通过私人缓存缓存,但共享缓存可能不会缓存响应.s-maxage=0添加的是因为private所有支持的代理可能都不支持Cache-Control(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3 - 我不知道哪些代理被破坏了).将max-age被设置为的值60*60*24*365(1年),因为HTTP/1.1规范没有定义该参数的任何上限,我想,这是依赖于实现的.该Expires头应该这样使用相同的逻辑在这里应该没问题仅限于一年以后.所述Vary: Cookie报头是必需的因为检查所使用的会话如果访问者被允许看到的内容被在cookie传送; 因为返回的响应取决于cookie值,如果更改了cookie标头,缓存可能不会使用缓存响应.
我可能会亲自打破最后一部分.通过不包括Vary: Cookie标题我可以改善缓存.例如:我有一个配置文件图像,http://domain.com/icon/12仅针对选定的经过身份验证的用户返回.我有一个X会话ID 的访问者,5f2我允许该用户的图像.访客X注销,然后再次登录.现在X会话ID 2e8存储在他的会话cookie中.如果有Vary: cookie,则用户代理X无法使用缓存的图像,并被迫将其重新加载到其缓存中.由于内容因Cookie而异,因此无法使用具有上次修改时间的条件GET.我没有测试ETag在这种情况下使用是否有帮助,因为在这种情况下,服务器响应将是相同的(匹配ETag从响应内容计算的SHA-1 ).请注意,Internet Explorer(至少版本9)总是强制对包含的资源进行条件GET Vary: Cookie(来源:http://blogs.msdn.com/b/ie/archive/2010/07/14/caching-improvements- in-internet-explorer-9.aspx).这是因为MSIE的内部缓存实现不记得它第一次发送哪个Cookie,因此无法知道当前Cookie是否是同一个Cookie.
但是,这是一个问题的示例,该问题是由于删除Vary: Cookie标题以显示为什么这确实是技术上正确的行为所必需的.请参阅上面的示例,并假设在X注销后,访问者Y使用相同的用户代理登录(用户代理可能已在X和Y之间重新启动,这无关紧要).如果Y查看包含链接的页面,http://domain.com/icon/12则Y将看到嵌入页面内的图标,即使Y先前未使用相同的用户代理,Y也无法看到该图标.在我的情况下,我不认为这是一个足够大的问题,因为Y可以通过检查用户代理缓存手动访问图标,无论可能添加Vary: Cookie.但是,此问题可能会阻止Y注意到他在技术上无法访问此内容(这可能很重要,例如,如果Y正在共同创作内容).如果内容被视为敏感内容,则no-store无论此Cache-Control指令引起的问题如何,服务器都必须发送.
在这里,添加Last-Modified标题将有助于用户点击重新加载/刷新按钮(参见上面的讨论).
不稳定的公共内容
Date: <current time>
Expires: <current time>
Cache-Control: public, max-age=0, s-maxage=0
Last-Modified: <real-last-modification-time>
Run Code Online (Sandbox Code Playgroud)
基本原理:告诉HTTP/1.0客户端和代理服务器应立即将此响应视为过时.该Last-Modified时间包括允许跳过当资源被再次访问和客户端支持有条件的GET内容数据传输.如果Last-Modified不能使用,ETag可以用作替代品(见上面的讨论).使用Last-Modified允许HTTP/1.0兼容客户端的条件GET 至关重要.
如果内容可被稍微延迟,然后Expires,max-age和s-maxage[原文如此]应适当地调节.例如,正如symcbean的回答所建议的那样,对那些增加5秒可能对非常受欢迎的网站有很大帮助.请注意,与条件GET不同,增加到期时间将减少服务器负载,而不是仅减少服务器传出数据流量(因为服务器总共会看到更少的请求).
不稳定的非公开内容
Date: <current time>
Expires: <current time>
Cache-Control: private, max-age=0, s-maxage=0
Last-Modified: <real-last-modification-time>
Vary: Cookie
Run Code Online (Sandbox Code Playgroud)
基本原理:告诉HTTP/1.0客户端和代理服务器应立即将此响应视为过时.该Last-Modified时间包括允许跳过当资源被再次访问和客户端支持有条件的GET内容数据传输.如果Last-Modified不能使用,ETag可以用作替代品(见上面的讨论).使用Last-Modified允许HTTP/1.0兼容客户端的条件GET 至关重要.另请注意,Cache-Control不得包含no-cache,must-revalidate或者no-store因为使用任何这些指令会破坏至少一个用户代理中的后退按钮.但是,如果服务器正在传输的内容包含不应存储在永久存储器中的敏感材料,则no-store必须使用该标志,而不管是否断开后退按钮.警告:请注意,no-store如果操作系统已启用交换且交换未加密,则使用无法阻止敏感材料在没有加密的情况下在硬盘上结束!另请注意,no-store除非连接已加密(HTTPS/SSL),否则使用很有意义.