浏览器缓存分为强制缓存和协商缓存
强制缓存就是浏览器向服务器请求资源,服务器响应头给予一个cache-control 或者expires ,在这个时间之内,就不会向服务器请求资源,但是强制缓存有个问题:如果服务端已经更新数据了,但是我们的本地浏览器还使用之前的旧数据,也就是使用本地的缓存,那么就不对了对吧,所以我们要使用协商缓存。
当然cache-control有几个常用的属性
- no-cache 使用协商缓存
- no-store不使用缓存,每次都要向服务器发送请求
- max-age=数字 缓存的时间
如果我们的cache-control是no-cache那么就是协商缓存了,就走协商缓存的逻辑
协商缓存的状态码是304,浏览器向服务器发送请求,服务器会根据请求头携带的一些参数来判断是否命中协商缓存,如果命中,那么就告诉我浏览器从自己的缓存中获取数据,否则就服务器返回新的数据
在浏览器访问服务器的时候,服务器会在响应头给予一个last-modify参数用来代表我资源文件最后一次的修改时间(记住存储的是时间)。那么浏览器再次发送请求的时候,会在请求头中携带一个if-modify-since
参数,这个数字大部分情况下是等于服务器响应头返回的last-modify,服务器接收到请求之后,会判断last-modify
和if-modify-since
是否相等,如果相等,就返回304,并告诉浏览器使用缓存,否则服务器返回一个新的文件数据。
但是使用last-modify
和if-modify-since
有一个缺点,如果我们这个文件用时300ms修改了,那么这个if-modify-since并没有改变,因为他只能精确到秒,文件已经修改了,但是if-modify-since
没有改变,所以并不严谨,我们就推出了新的参数Etag
和if-none-match
Etag
可以理解成是last-modify
,if-none-match
Etag
是加载资源时,服务器返回的响应头字段,是对资源的唯一标记,值是hash码(md5)。Hash
值是根据不同的文件,生成的一个字符串- 浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到请求头里的If-None-Match
- 服务器接收到
If-None-Match
的值后,会拿来跟该资源文件的Etag值做比较,如果相同,则表示资源文件没有发生改变,命中协商缓存。