HTTP缓存

HTTP缓存可以分为强缓存和协商缓存,浏览器请求一个页面的简单流程如下:

  1. 浏览器会根据资源的 HTTP 头信息来判断是否命中强缓存。如果命中则直接在缓存中获取资源,并不会将请求发送到服务器。
  2. 如果未命中强缓存,则浏览器会将请求发送到服务器,由服务器来判断资源是否失效,如果失效就将返回最新资源,没有失效就返回 304,这个过程被称为协商缓存。
  3. 如果未命中协商缓存,会将请求发送到服务器,服务器返回最新资源,并更新缓存。

强缓存

命中强缓存时,浏览器不会发送请求到服务器。请求的返回码是200,但是在 Size 列会显示为 (from cache) 。强缓存是利用 HTTP 的返回头中的 Expires 或者 Cache-Control 两个字段来控制的,用来表示资源的缓存时间。

Expires

缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,Expires = max-age + 请求时间,需要和 Last-modified 结合使用。

Cache-Control

Cache-Control 是一个相对时间,例如 Cache-Control: 3600 ,代表着资源的有效期是 3600 秒。由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问题。
Cache-ControlExpires 可以在服务端配置同时启用或者启用任意一个,同时启用的时候 Cache-Control 优先级高。
Cache-Control 取值:

  1. max-age: 指定一个时间长度,在这个时间段内缓存是有效的,单位是 s 。
  2. s-maxage: 同 max-age,覆盖 max-age、Expires,但仅适用于共享缓存,在私有缓存中被忽略。
  3. public: 表明响应可以被任何对象(发送请求的客户端、代理服务器等等)缓存。
  4. private: 表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存,是非共享的,不能被代理服务器缓存。
  5. no-cache: 不强制缓存,但是协商缓存。
  6. no-store: 不缓存

协商缓存

若未命中强缓存,则浏览器会将请求发送至服务器。服务器根据 HTTP 头信息中的 Last-Modify / If-Modify-SinceEtag / If-None-Match 来判断是否命中协商缓存。如果命中,则 HTTP 返回码为304,浏览器从缓存中加载资源。Last-ModifiedETag 是可以一起使用的,服务器会优先验证 ETag ,一致的情况下,才会继续比对 Last-Modified ,最后才决定是否返回 304

Last-Modify / If-Modify-Since
  1. 浏览器第一次请求一个资源时,服务器的响应头中会添加一个 Last-Modify 是一个时间标识,标识请求资源最后一次变动时间。
  2. 下次请求时,浏览器端会在请求头中添加 If-Modify-Since ,值是缓存之前返回的 Last-Modify
  3. 服务器接收后对比 If-Modify-Since 和资源最后一次修改的时间,如果没变化则命中协商缓存,返回 304 ,如果变化就返回最新资源。
ETag / If-None-Match

Last-Modify / If-Modify-Since 不同的是,Etag / If-None-Match 返回的是一个校验码(ETag: entity tag)。ETag 可以保证每一个资源是唯一的,资源变化都会导致 ETag 变化ETag 值的变更则说明资源状态已经被修改。服务器根据浏览器上发送的 If-None-Match 值来判断是否命中缓存。

用户行为与缓存

浏览器缓存行为还有用户的行为有关,当进行某些操作是,是强制不缓存的:

用户操作 Expires / Cache-Control Last-Modified / Etag
地址栏回车 有效 有效
页面链接跳转 有效 有效
新开窗口 有效 有效
前进、后退 有效 有效
F5刷新 无效 有效
Ctrl + F5刷新 无效 无效

你可能感兴趣的:(JavaScript)