重点掌握:
- 强缓存:Expires, cache-control
- 协商缓存:Last-Modified/ If-Modified-Since, ETag/ If-None-Match
- 状态码304
强缓存
- 缓存数据未失效的情况下,那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。
- 可以通过设置两种 HTTP Header 实现:Expires 和 Cache-Control
- 判断过期:
- HTTP1.0:Expires的缓存时间没有过期
- HTTP1.1:Cache-Control的max-age没有过期
- 强制缓存生效时,http状态码为200,chrome中缓存从两种地方获取:
- from memory cache (从内存中获取/一般缓存更新频率较高的js、图片、字体等资源)
- from disk cache (从磁盘中获取/一般缓存更新频率较低的js、css等资源)
Expires
HTTP1.0的强缓存,值为过期时间(秒级)时间戳,现在基本不用,优先考虑Cache-Control
缺点:存储的是服务器的时间,无法应对客户端的时间和服务器端的时间不一致,或者用户可以对客户端时间进行修改的情况
Cache-Control
HTTP1.1的强缓存,置为有效时间(秒级)
- 例如,max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。
属性:
public
:设置了该字段值的资源表示可以被任何对象(包括:发送请求的客户端、代理服务器等等)缓存。这个字段值不常用,一般还是使用max-age=来精确控制;private
:设置了该字段值的资源只能被用户浏览器缓存,不允许任何代理服务器缓存。在实际开发当中,对于一些含有用户信息的HTML,通常都要设置这个字段值,避免代理服务器(CDN)缓存;no-cache
:客户端缓存内容,是否使用缓存则需要经过协商缓存来验证决定。- 表示不使用 Cache-Control的缓存控制方式做前置验证,而是使用 Etag 或者Last-Modified字段来控制缓存。
no-store
:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存(memory cache也会失效)**
max-age
**:max-age=xxx 表示缓存内容将在xxx秒后失效
当两种强缓存方式一起使用时,Cache-Control 的优先级要高于 Expires
协商缓存
- 协商缓存就是强缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
- 可以通过设置两种 HTTP Header,Last-Modified或者ETag实现
- 判断过期:当浏览器第一次向服务器发送请求时,会在响应头中返回协商缓存的头属性:ETag和Last-Modified
- HTTP 1.0:Last-Modified/If-Modified-Since
- Last-Modified返回的是GMT格式的最后修改时间(只能判断秒级修改)
- 浏览器在第二次发送请求的时候,会在请求头中带上与Last-Modified对应的If-Modified-Since,值为最后修改时间
- HTTP 1.1:ETag/If-Not-Match
- ETag返回的是一个hash值
- 浏览器在第二次发送请求的时候,会在请求头中带上与ETag对应的If-Not-Match,值为Etag的hash值
- HTTP 1.0:Last-Modified/If-Modified-Since
- 如果服务器资源未修改,返回304,如果有修改,返回200和新资源
Last-Modified
Last-Modified/ If-Modified-Since
HTTP1.0的协商缓存,值为资源文件最后一次更改时间(秒级)
缓存过程:
- 浏览器第一次请求资源
- 服务器通过在响应头中添加 Last-Modified 属性来指出资源最后一次修改的时间,
- 浏览器下一次发起请求时
- 浏览器在会在请求头中添加一个 If-Modified-Since 的属性,属性值为上一次资源返回时的 Last-Modified 的值。
- 服务器会通过这个属性来和资源的最后一次的修改时间来进行比较,以此来判断资源是否做了修改。
- 如果资源没有修改,那么返回 304 状态,让客户端使用本地的缓存。
- 如果资源已经被修改了,则返回200状态和修改后的资源。
缺点:
- 因为是秒级,如果某些文件在1秒钟以内,被修改多次的话,那么文件已将改变了但是 Last-Modified 却没有改变,这样会造成缓存命中的不准确
- 可能资源被修改过,但是值未发生变化,这种时候也不算已修改
Etag
Etag/ If-None-Match
全程Entity Tag,值是资源生成的唯一标识符,对输入敏感,资源发生改变后ETag也改变,可以解决Last-Modified问题
- 生成Etag的方法有很多,通常是使用内容的散列、最后修改时间戳的哈希值或简单地使用版本号
缓存过程:和Last-Modified类似
- 浏览器第一次请求资源
- 服务器在返回资源的时候,在头信息中添加了 Etag 属性
- 浏览器下一次发起请求时
- 浏览器会在请求头中添加一个 If-None-Match 属性,这个属性的值就是上次返回的资源的 Etag 的值。
- 服务接收到请求后会根据这个值来和资源当前的 Etag 的值来进行比较,以此来判断资源是否发生改变,是否需要返回资源。