浏览器缓存
介绍一下浏览器的缓存机制,它是怎么工作的?
TIP
浏览器第一次加载资源,服务端返回
200
,浏览器从服务器下载资源文件,并缓存资源文件和响应头response header
,以供下次加载时对比使用。在第二次加载资源时,由于强缓存的优先级更高,先比较当前时间与上一次返回
200
时的时间差,如果没有超过cache-control
设置的max-age
,则表示缓存还没有过期,命中强缓存,直接从本地读取资源。如果浏览器不支持HTTP1.1
,则使用expires
头来判断是否过期。如果资源已经过期,则表示强缓存没有被命中,则开始协商缓存,向服务器发送带有
If-None-Match
和If-Modified-Since
的请求服务器收到请求后,优先根据
ETag
的值判断被请求的文件有没有被修改,ETag
值一致则没有修改,命中协商缓存,返回304
;如果不一致则表明有改动,直接返回新的资源文件,并带上新的ETag
值 和200
的状态码如果服务器收到的请求没有
ETag
值,则将If-Modified-Since
的值与服务器上的文件最后修改时间进行对比,如果一致则命中协商缓存,返回304
;如果不一致则表明有改动,直接返回新的资源文件,并带上新的Last-Modified
值 和200
的状态码
总的来说顺序就是
cache-control > expires > ETag > Last-Modified
需要特别注意的是
Expires
标头也可以指定缓存过期时间,例如 Expires: Thu, 30 Dec 2021 12:00:00 GMT
表示资源在该日期之前可被缓存。但这种方式已经不太常用,因为它依赖于客户端和服务器端的时间同步,容易出现问题。
Last-Modified
和 ETag
则用于检查资源是否发生变化。Last-Modified
指定了资源的最后修改时间,而 ETag
是服务器生成的唯一标识符。当浏览器第一次请求资源时,服务器会将这些信息一起返回。当浏览器再次请求资源时,它会将上次请求中响应头中的这些信息包含在 if-modified-since
或 if-none-match
请求头中。如果资源没有变化,则服务器将返回一个状态码为 304
的响应,告诉浏览器可以使用缓存中的资源。