摘要:HTTP 缓存相关知识
缓存的规则
HTTP 缓存分为强制缓存和协商缓存,且强制缓存的优先级高于协商缓存。
强制缓存
如果缓存数据库中有客户端需要的数据且数据未失效过期,那么客户端会直接使用该数据,请求返回的状态码都是 200,并且 Size 代表该缓存的位置;如果没有命中缓存,客户端才会向服务端发起请求。
存放缓存数据的位置有两处:
1、内存缓存(memory cache)
内存缓存会将编译解析后的文件,直接存入该进程的内存中。但如果进程关闭,则该进程的内存以及其中的缓存数据都会清空。一般脚本、字体、图片会存在内存当中。
2、硬盘缓存(disk cache)
硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行 I/O 操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢,但存储的量比内存大得多。css 一般会存入硬盘中。
访问缓存优先级是:内存缓存 -> 硬盘缓存 -> 网络请求
设置强制缓存的两种方法:
1、Expires
Expires 的值为服务端返回的数据到期时间。如果再次请求该数据时还在有效期内,则直接使用缓存数据。但客户端和服务端的时间可能有误差,而且 Expires 是 HTTP1.0 的产物,现在大多使用第二种方法
2、Cache-Control
该字段有很多属性,且这些属性可以自由组合。Cache-Control 的优先级高于 Expires。常见的属性有:
1)private:客户端可以缓存
2)public:客户端和代理服务器都可以缓存
3)max-age=t:缓存内容将在 t 秒后失效
4)no-cache:可以缓存,但每次使用都要向服务端评估缓存的有效性
5)no-store:所有内容都不会缓存,其优先级最高
协商缓存
客户端会先从缓存数据库拿到一个缓存的标识,然后向服务端验证标识是否失效,如果没有失效服务端会返回 304 状态码,客户端接收到后会使用该缓存数据;如果失效,服务端会返回新的数据给客户端。
设置协商缓存的两种方法:
1、Last-Modified/if-Modified-Since
服务器在首次响应请求时,会通过 Last-Modified 字段告诉浏览器对应数据的最后修改时间。浏览器再次请求该数据时,会在请求头添加 if-Modified-Since 字段,字段后面跟着在缓存中获得的最后修改时间。服务端收到此请求头发现有 if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果数据没有发生改变,那么服务端返回 304 状态码,客户端从缓存中获取数据;如果数据更新了,那么服务端会返回 200 状态码和更新的数据,并且更新 Last-Modified 为新的值。
2、Etag/If-None-Match
服务器响应请求时,通过 Etag 字段告诉浏览器当前资源在服务器生成的唯一标识(生成规则由服务器决定)。当再次请求服务器时,浏览器的请求头会包含 If-None-Match 字段,字段后面的值为在缓存中获取的标识。服务器接收到次报文后发现 If-None-Match 则与被请求资源的唯一标识进行对比。与 Last-Modified 相似,如果标识相同,说明数据没有发生变化,那么服务端返回 304 状态码,客户端从缓存中获取数据;如果标识不同,说明资源被改动过,则服务端返回状态码 200 状态和更新的数据,并且更新 Etag 为新的值。