浏览器缓存分为两种,强缓存和协商缓存。浏览器缓存的流程大致如下:
强缓存
强缓存就是图中第一个判定条件。有两种方式判断浏览器的强缓存,Cache-Control和Expires。Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
协商缓存
协商缓存是当强缓存失效后,浏览器端发起请求并携带一个字段到服务端,服务端判断文件是否更新的方式。同样也有两种方式,Last-Modified和Etag。
Last-tModified
与Last-Modified匹配的是If-Modified-Since。当第一次请求某一个文件的时候,就会传递回来一个Last-Modified 字段,其内容是这个文件的修改时间。当这个文件缓存过期,浏览器又向服务器请求这个文件的时候,会自动带一个请求头字段If-Modified-Since,其值是上一次传递过来的Last-Modified的值,拿这个值去和服务器中现在这个文件的最后修改时间做对比,如果相等,那么就不会重新拉取这个文件了,返回304让浏览器读过期缓存。如果不相等就重新拉取。-
Etag
和Etag匹配的是if-nono-match,Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,通过Etag来区分两个资源是否一致,随response返回和请求头的if-none-match相比较,判断资源在两次请求中是否修改。在有了Last-Modified后,为什么需要Etag的出现呢?Etag主要解决了Last0Modified以下几个痛点:
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的新鲜度
- 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
最后,需要知道的是,Last-Modified与Etag是可以一起使用的,服务器会优先验证Etag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。