国内关于缓存的概念

国内将缓存分类为:强缓存和协商缓存。

这两者的区别在于:

强缓存如果命中了,则不需要向服务器确认是否有效。

而协商缓存,没有命中强缓存,还是会向服务器确认是否有效。(也就是说即使过期了,也不代表这缓存和原始服务器上的文件有区别)

也就是说判断是强缓存还是协商缓存的标准在于:

(缓存没有命中的时候)是否需要向服务器确认是否有效。

其中 Expires 和 Cache-control 属于强缓存;Last-Modified/If-Modified-Since 和 Etag/If-None-Match 属于协商缓存。摘自:[前端开发]几种你不得不了解的浏览器缓存设置方式 - 知乎

强缓存

什么是强缓存

如果命中了缓存,那么就直接使用缓存。

怎么实现强缓存

  1. 如果是 http1.0 的话,使用 Expires 来实现
    expires 后面会跟一个过期的时间,如果当前客户端的系统时间比这个时间晚的话,就代表过期了。 这么做缺点也比较明显了,是否过期与当前客户端的时间强关联, 修改了客户端的系统时间的话,会影响判断。

  2. 如果是 http1.1 的话,使用 cache control 来实现
    备注:cache control 的优先级是要比 expires 要高的,同时出现的话按照前者来。 cache control 是使用 max-age 以及 age 来判断的,max-age 是一个相对的时间。 max-age 指的是在生成相应的时间到当前时间的 N 秒中,缓存都是新鲜的有效的,不需要重新获取。 age 指的是目前已经缓存的时间。

也就是说如果 age 存在,那么还有多久过期的时间就是 max-age 减去 age。

协商缓存

什么是协商缓存

如果没有命中缓存,向服务器验证后确保缓存没有失效才使用缓存。

怎么实现协商缓存

  1. 使用 Last-Modified,If-Modified-Since

If-Modified-Since 是在请求头中的,Last-Modified 是在响应头中的。

但是如果本地的缓存被修改了之后,它的修改时间是会变化的,所以 If-Modified-Since 也是有改变的可能的。

  1. 用 eTag、If-None-Match eTag = entity tag

Last-Modified 的缺陷:

(来自 HTTP权威指南-David Gourley Brian Totty等

If-None-Match 是请求头里的,值的话就是当前缓存中的 tag 有哪些

If-None-Match 可以传入 etag_value 也不难理解,可以一次请求验证多个,哪个 tag 有效就用哪个。

eTag 是响应头里的

为什么说强缓存和协商缓存是国内的标准

感觉越看越觉得强缓存和协商缓存没必要放在一起说

参考资料

缓存(二)——浏览器缓存机制:强缓存、协商缓存 · Issue #41 · amandakelake/blog · GitHub

Cache-Control explained - DEV Community

HTTP 缓存策略:强缓存和协商缓存 - 掘金

[前端开发]几种你不得不了解的浏览器缓存设置方式 - 知乎