缓存位置
- 分为4种,各自有优先级,当查找缓存都没有命中时,才会去请求网络
- Service Worker,浏览器背后的独立线程,实现缓存功能
- Memory Cache,内存中的缓存,主要包含当前页面中已抓取到的资源
- Disk Cache,硬盘中的缓存,
- Push Cache,当以上3种缓存没有时才会被使用,它只在会话(session)中存在,一旦会话结束就被释放,并且缓存时间也很短
缓存方式
-
强缓存,不会向服务器发送请求,直接从缓存中读取资源,可以通过Expires和Cache Control实现
- Expires:缓存过期时间,用来指定资源到期时间。缺点:如果修改了本地时间,可能会造成缓存失效
- Cache Control:指定缓存有效时间(可以理解为保质期),当计时超出有效时间以后缓存失效
-
协商缓存,强制缓存失效后,浏览器携带缓存标识向服务器发送请求,由服务器发送缓存标识决定是否使用缓存,可以通过设置两种HTTP Header实现:Last Modified和ETag
Last Modified和if-Modified-Since:浏览器第一次返回页面时,服务端返回资源时,在response header中添加 Last-Modified的header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和header,浏览器下一次请求这个资源,浏览器检测到有 Last-Modified这个header,于是添加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匹配不上,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端;如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。
一般会优先使用强缓存