答:浏览器缓存的作⽤是什么
- 缓存可以减少冗余的数据传输。节省了⽹络带宽,从⽽更快的加载⻚⾯。
- 缓存降低了服务器的要求,从⽽服务器更快的响应
缓存的资源⽂件到什么地⽅去了呢?
那么⾸先来看下 memory cache 和 disk cache 缓存
- memory cache: 它是将资源⽂件缓存到内存中。等下次请求访问的时候不需要重新下载资源,⽽ 是直接从内存中读取数据。
- disk cache: 它是将资源⽂件缓存到硬盘中。等下次请求的时候它是直接从硬盘中读取
浏览器缓存分为2种:强制缓存和协商缓存
协商缓存原理:
- 客户端向服务器端发出请求,服务端会检测是否有对应的标识,如果没有对应的标识,服务器端会 返回⼀个对应的标识给客户端,客户端下次再次请求的时候,把该标识带过去,然后服务器端会验 证该标识,如果验证通过了,则会响应304,告诉浏览器读取缓存。如果标识没有通过,则返回请 求的资源。
那么协商缓存的标识⼜有2种:ETag/if-None-Match 和 Last-Modified/if-Modify-Since
- 协商缓存Last-Modified/if-Modify-Since
浏览器第⼀次发出请求⼀个资源的时候,服务器会返回⼀个last-Modify到hearer中. Last-Modify 含义是最后的修改时间。 当浏览器再次请求的时候,request的请求头会加上 if-Modify-Since,该值为缓存之前返回的 LastModify. 服务器收到if-Modify-Since后,根据资源的最后修改时间(last-Modify)和该值(if-ModifySince)进⾏⽐较,如果相等的话,则命中缓存,返回304,否则, 如果 Last-Modify > if-ModifySince, 则会给出200响应,并且更新Last-Modify为新的值。
- 协商缓存ETag/if-None-Match
ETag的原理和上⾯的last-modified是类似的。ETag则是对当前请求的资源做⼀个唯⼀的标识。该 标识可以是⼀个字符串,⽂件的size,hash等。只要能够合理标识资源的唯⼀性并能验证是否修改过 就可以了。ETag在服务器响应请求的时候,返回当前资源的唯⼀标识(它是由服务器⽣成的)。但是 只要资源有变化,ETag会重新⽣成的。浏览器再下⼀次加载的时候会向服务器发送请求,会将上⼀ 次返回的ETag值放到request header ⾥的 if-None-Match⾥⾯去,服务器端只要⽐较客户端传来 的if-None-Match值是否和⾃⼰服务器上的ETag是否⼀致,如果⼀致说明资源未修改过,因此返回 304,如果不⼀致,说明修改过,因此返回200。并且把新的Etag赋值给if-None-Match来更新该 值。
last-modified 和 ETag之间对⽐:
- 在精度上,ETag要优先于 last-modified。
- 在性能上,Etag要逊于Last-Modified,Last-Modified需要记录时间,⽽Etag需要服务器通过算法 来计算出⼀个hash值。
- 在优先级上,服务器校验优先考虑Etag
强缓存
- 基本原理:浏览器在加载资源的时候,会先根据本地缓存资源的header中的信息(Expires 和 Cache-Control)来判断是否需要强制缓存。如果命中的话,则会直接使⽤缓存中的资源。否则的 话,会继续向服务器发送请求。
- Expires
Expires 是http1.0的规范,它的值是⼀个绝对时间的GMT格式的时间字符串。这个时间代表的该资 源的失效时间,如果在该时间之前请求的话,则都是从缓存⾥⾯读取的。但是使⽤该规范时,可能 会有⼀个缺点就是当服务器的时间和客户端的时间不⼀样的情况下,会导致缓存失效
- Cache-Control
Cache-Control 是http1.1的规范,它是利⽤该字段max-age值进⾏判断的。该值是⼀个相对时 间,⽐如 Cache-Control: max-age=3600, 代表该资源的有效期是3600秒。除了该字段外,我们 还有如下字段可以设置:
- no-cache: 需要进⾏协商缓存,发送请求到服务器确认是否使⽤缓存。
- no-store:禁⽌使⽤缓存,每⼀次都要重新请求数据。
- public:可以被所有的⽤户缓存,包括终端⽤户和 CDN 等中间代理服务器。
- private:只能被终端⽤户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。
- Cache-Control 与 Expires 可以在服务端配置同时启⽤,同时启⽤的时候 Cache-Control 优先级高