前端缓存分为两大类:HTTP缓存和浏览器缓存
本文重点讲解下HTTP缓存的一些知识点。
一、 http请求缓存过程
- 浏览器第一次请求资源时,服务器返回资源,并在respone header头中回传资源的缓存参数,浏览器将其进行缓存;
- 第二次请求时,浏览器判断这些请求参数,命中强缓存就直接
200
,否则就把请求参数加到request header头中传给服务器,看是否命中协商缓存,命中则返回304
,否则服务器会返回新的资源。
二、 http缓存分类
根据是否需要向服务器重新发起HTTP请求将缓存过程分为两个部分:强缓存和协商缓存
1. 强缓存
强缓存不会向服务器发送请求,直接从缓存中读取资源。
可以通过设置三种http header实现,优先级从高到低为:
Pragma --> Cache-Control --> Expires
- Pragma:http1.0的产物,值为
no-cache
时禁用缓存,现常用来做http的向下兼容。 - Cache-Control:用于控制缓存的行为,是一个通用首部字段,可组合多种指令使用。
指令 | 作用 |
---|---|
public | 表示响应可以被客户端和代理服务器缓存 |
private | 表示响应只可以被客户端缓存 |
no-cache | 资源被缓存,但是立即失效,下次会发起请求验证资源是否过期 |
no-store | 不缓存任何响应 |
max-age=xx | 缓存xx秒后就过期,需要重新请求 |
s-maxage=xx | 覆盖max-age,作用一样,只在代理服务器中生效 |
max-stale=xx | 表示xx秒内,即使缓存过期,也使用该缓存 |
min-fresh=xx | 希望在xx秒内获取最新的响应 |
- Expires:缓存过期时间,用来指定资源到期的时间,是服务器端具体的时间点。
2. 协商缓存
在强缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用协商缓存。
主要有以下两种情况:
- 协商缓存生效,返回304和not modified。
- 协商缓存失效,返回200和请求结果。
可以通过设置两种http header实现,优先级从高到低为:
ETag/If-None-Match --> last-modified/If-Modified-Since
-
Last-Modified/If-Modified-Since
浏览器在第一次请求资源时,服务器返回资源的同时,在response header中添加Last-Modified
,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和header;
浏览器在下一次请求这个资源时,检测到header中有Last-Modified
,于是添加If-Modified-Since
到header中,值就是Last-Modified
的值;
服务器再次收到这个资源请求,会根据If-Modified-Since
中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304
和空的响应体,直接从缓存读取,如果If-Modified-Since
的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200
。 -
ETag/If-None-Match
ETag
是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,ETag
就会重新生成。
浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的ETag
值放到request header里的If-None-Match
里,服务器只需要比较客户端传来的If-None-Match
跟自己服务器上该资源的ETag
是否一致,就能很好地判断资源相对客户端而言是否被修改过了。
如果服务器发现ETag
匹配不上,那么直接以常规GET200
回包形式将新的资源(当然也包括了新的ETag
)发给客户端;
如果ETag
是一致的,则直接返回304
知会客户端直接使用本地缓存即可。