适用于不同类型资源的理想 HTTP 缓存控制标头

Posted

技术标签:

【中文标题】适用于不同类型资源的理想 HTTP 缓存控制标头【英文标题】:Ideal HTTP cache control headers for different types of resources 【发布时间】:2021-03-17 13:38:02 【问题描述】:

我想找到一组最小的标头,它们适用于“所有”缓存和浏览器(在使用 HTTPS 时也是如此!)

在我的网站上,我将拥有三种资源:

(1) 永久可缓存(公共/对所有用户均等)

示例:0A470E87CC58EE133616F402B5DDFE1C.cache.html (auto generated by GWT)

这些文件在更改内容时会自动分配一个新名称(基于 MD5)。

即使使用 HTTPS,它们也应该尽可能多地被缓存(所以我假设,我应该设置 Cache-Control: public,尤其是对于 Firefox?)

如果内容已更改,它们不应要求客户端往返于服务器进行验证。

(2) 偶尔更改(公共/所有用户平等)

示例:index.html、mymodule.nocache.js

当部署新版本的站点时,这些文件会更改其内容而不更改 URL。

它们可以被缓存,但可能每次都需要往返重新验证。

(3) 每个请求的个体(私人/用户特定)

示例:JSON 响应

在任何情况下都不应将这些资源未加密地缓存到磁盘。 (也许我会有一些可以缓存的特定请求。)

我大致了解每种类型可能使用哪些标头,但总有一些我可能会遗漏的东西。

【问题讨论】:

感谢您的回答以及 cmets 和链接。我还在尝试,但我认为,我将能够得出一个解决方案! 实现#3 通常是不可能的。 另见:***.com/questions/6491789/… 【参考方案1】:

我可能会使用这些设置:

    Cache-Control: max-age=31556926 – 表示可以被任何缓存缓存。缓存的表示将被视为新鲜 1 年:

    为了将响应标记为“永不过期”,源服务器发送一个 Expires 日期从响应时间算起大约一年 发送。 HTTP/1.1 服务器不应发送超过一个 Expires 日期 未来一年。

    Cache-Control: no-cache – 表示可以被任何缓存缓存。但是缓存必须在释放缓存副本之前将请求提交给源服务器进行验证。 Cache-Control: no-store – 缓存在任何情况下都不得缓存表示。

更多信息请参见Mark Nottingham’s Caching Tutorial

【讨论】:

@Gumbo:我很确定的一件事是,当我希望 Firefox 3+ 在使用 HTTPS 时将公共文件缓存到磁盘时,我需要设置 public :***.com/questions/174348/… 一些浏览器,例如 IE,开始将 Cache-Control: no-cache 当作 no-store 对待。诚然,这不符合 RFC,但它是故意“修复”许多人所犯的错误,即使用无缓存来防止敏感数据未加密地存储在磁盘上。 @chris_l,我偶然发现了这个链接:palisade.plynt.com/issues/2008Jul/cache-control-attributes。我不记得以前的版本表现如何,虽然我认为 IE7 也是这样做的。 此外,Firefox 不再需要 Cache-Control 中的 PUBLIC 来缓存 HTTPS 资源。但总体而言,您最好的选择是在观察流量的同时测试您的网站,例如与提琴手。 不建议将缓存控制值设置为 100 年。首先,规范建议最长为 1 年。其次,任何超过 68 年的值都会导致 IE8 及以下版本立即到期:blogs.msdn.com/b/ieinternals/archive/2010/01/26/…【参考方案2】:

案例一和二其实是同一个场景。 您应该设置Cache-Control: public,然后生成一个包含站点内部版本号/版本的 URL,这样您就可以拥有可能永远存在的不可变资源。 您还希望将 Expires 标头设置为未来一年或更长时间,以便客户端不需要发出新鲜度检查。

对于案例 3,您可以采用以下所有方法以获得最大的灵活性:

"Cache-Control", "no-cache, must-revalidate"
"Expires", 0
"Pragma", "no-cache"

【讨论】:

新构建的不同 URL 可能不是一种选择:a) 这将迫使客户端重新下载永久可缓存的文件。他们获得独特的名称以避免这种情况。 b) 我网站的主要 URL 应该只是 https://www.example.com/ c) 我希望书签始终引用我网站的最新版本(想象一下,*** 问题的书签将包含网站的内部版本号)。跨度> 嗨 Chris,这种方法通常用于 CSS 和 JS 资源而不是文档。我同意它不适用于文档标识符,在这种情况下,您应该简单地在标题上设置缓存控制 public、Last-Modified 和 etag,这将导致每次都进行新鲜度检查,如果没有更改,则只会发回 304自上次下载以来。或者,您可以通过 JS 下载每个页面中的实际动态页面内容,以便在保留 URL 的同时仍然允许有效缓存。 是的,差不多就是这样,GWT 为我处理这个问题:我的 index.html(偶尔更改)包含 mymodule.nocache.js(偶尔更改),它会自动包含正确的永久缓存文件(大部分 js,GWT 管理的图像包,...)它留给我的唯一一件事就是为每种类型设置正确的 http 标头。我想将这些标头减少到最低限度,因为它们占传输量的很大比例。所以我需要例如Last-Modified ETag等? "Expires" 实际上需要是一个日期,而不是数字 0。它应该与 "Date" 标头具有相同的值。见mnot.net/cache_docs

以上是关于适用于不同类型资源的理想 HTTP 缓存控制标头的主要内容,如果未能解决你的问题,请参考以下文章

Firefox 避免缓存响应?

Web缓存控制策略详解

HTTP静态资源缓存永远策略

使IE缓存资源但始终重新验证

广电媒资理想的分布式存储EonStor CS

跨域请求被阻止:同源策略不允许读取远程资源,CORS 标头中缺少令牌“缓存控制”