You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.
Cache directives are unidirectional in that the presence
of a directive in a request does not imply that the same directive is
to be given in the response.
对于cache-request-directive 以max-age为例:
max-age Indicates that the client is willing to accept a response whose age is no greater than the specified time in seconds. Unless max-stale directive is also included, the client is not willing to accept a stale response
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
一些疑点
request 中的 cache-control vs. response 中的 cache-control
cache-control 作为一个 general header,在 request 和 response 中都可以存在?那么如果假设我们在某 HTML 的 meta 中写了
但是和这个 HTML 的 response 中由服务器设定的 cache-control 不一致时,如下图,demo
下一次请求的 cache-control 该听谁的呢?
在这个例子中,重复访问页面,第二次访问的 HTML 是 from disk,也就是说缓存生效了。
MDN 中语焉不详,只是说 a given directive in a request is not implying that the same directive is to be given in the response。我也没在 HTTP 规范中找到对应的规则。
查了一下资料,发现这应该是一个由服务器来控制的规则:服务器可以选择是否忽略 request 中的 cache-control,如果不忽略就按 request 中的 cache-control 规则来,忽略了就按 response 中的 cache-control 规则来。
比如Apache
比如 Nginx
策略
不缓存
再加上兼容 HTTP/1.0 的 expires 和 pragma,即禁止一切缓存,请求每次都要发往源服务器。
长 max-age + 指纹
将 Cache-Control 设定的很长,即在 Cache-Control 没有过期的情况下将直接从浏览器中取出缓存(from memory cache 或 from disk cache),但是这样也彻底限制了资源更新的可能。
通过给资源的 URL 添加一个“指纹”,可以是版本号,hash,MD5 或日期等。
通过 HTML 的更新来控制对应资源是否更新,这样做的好处是在 HTML 没更新的时候直接从浏览器中取缓存,有效避免 304,进一步减小服务器的压力;HTML 更新后也会更新资源文件的文件名,URI 变了浏览器自然会去向源服务器请求新的资源。
知乎 & 掘金 & GitHub
我们通过分析知乎和掘金的的 HTTP 缓存实践来看下这两个网站是如何进行缓存的:
知乎
*.html
知乎的主页是由服务端动态生成的,所以采用完全不缓存的策略。
*.js, *.css
.js 和 .css 采用的都是长 max-age + 指纹 的策略,由上面的 HTML 来控制是否更新。
静态资源
图片等同样适用 max-age + 指纹 的策略。
Ajax
对于涉及到用户个人的信息,要特别在 cache-control 中指出 private 来防止缓存服务器缓存,然后再禁止掉所有本地缓存。
掘金
*.html
掘金的 HTML 只在 Cache-Control 中写了 private,禁止缓存服务器缓存,但是也没有指定 max-age,所以每次还是会去请求源服务器。
不过根据 MSDN 中描述的,Cache-Control 默认值就是 private,所以不写应该也没问题。
*.js, *.css
对于加指纹的文件,与知乎的策略近似,这里多了一个 public,意欲何为?
静态资源
资源文件有指纹,所以采用长 max-age + 指纹的策略,又多了个 public?
Ajax
采用长 max-age + 指纹的策略并且不允许缓存服务器缓存。
GitHub
*.html
采用 no-cache,这样可以利用缓存服务器,缓存服务器在发回备份前会先向源服务器确认缓存是否可用,如果可用则返回给浏览器备份,否则要再向源服务器发起请求。
*.js, *.css
同掘金
静态资源
不同于前两者的资源 URI,github 的资源 URI 采用的是
{id}?s={size}&v={version}
的格式,没有 指纹的加持,就要保证资源在改变时及时更新,github 是默认给缓存五分钟,五分钟之内直接从本地浏览器缓存中拿,如果超过了五分钟则去比较 Etag,Last-Modified 和 Expires,如果改变了就向源服务器 200 一个新的,如果没改变就会返回一个 304。
Ajax
同 html。
总结
HTTP 缓存不存在银弹,只有根据当前业务特点还有后端资源的配置寻求最适合的配置。
参考
The text was updated successfully, but these errors were encountered: