HTTP缓存机制

HTTP缓存机制主要由以下三部分组成

缓存存储策略

这个策略的作用只有一个,用于决定 Http 响应内容是否可缓存到客户端。主要通过Cache-Control来控制。

  • Cache-Control

    • max-age

    • public

    • private

    • no-cache

    • no-store

除了no-store其他都会被缓存到客户端。

缓存过期策略

这个策略的作用也只有一个,那就是决定客户端是否可直接从本地缓存数据中加载数据并展示(否则就发请求到服务端获取)

数据缓存到了本地后还需要经过判断才能使用,那么浏览器通过什么条件来判断呢? 答案是:Expires,Expires 指名了缓存数据有效的绝对时间,告诉客户端到了这个时间点(比照客户端时间点)后本地缓存就作废了,在这个时间点内客户端可以认为缓存数据有效,可直接从缓存中加载展示。

缓存对比策略

将缓存在客户端的数据标识发往服务端,服务端通过标识来判断客户端 缓存数据是否仍有效,进而决定是否要重发数据。

客户端检测到数据过期或浏览器刷新后,往往会重新发起一个 http 请求到服务器,服务器此时并不急于返回数据,而是看请求头有没有带标识( If-Modified-Since、If-None-Match)过来,如果判断标识仍然有效,则返回304告诉客户端取本地缓存数据来用即可(这里要注意的是你必须要在首次响应时输出相应的头信息(Last-Modified、ETags)到客户端)。如果判断标识无效,则返回200,用新数据替换客户端缓存。

ETags, If-None-Match

Etag是指根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是否已经修改

Last-Modified, If-Modified-Since

这两个是HTTP1.0中用来验证资源是否过期的请求/响应头,这两个头部都是日期,验证过程与Etag类似。

总结

Http 缓存机制实际上是 Http 缓存策略三个要素(纬度)相互作用的集合,所以在分析和设置 Http 报文缓存头时,只要能从中精准的分解出缓存三要素,我们就能非常准确的预判到缓存设置最终能达到的效果。

实践

在html文件头部加上如下标签,能使该文件每次去服务端做对比,若不同则返回新文件,若相同则取客户端缓存。

<meta http-equiv="pragma" content="no-cache"> 
<meta http-equiv="cache-control" content="no-cache">  
<meta http-equiv="expires" content="0">

或是在项目中添加NoCacheFilter.java文件,响应头添加相关属性

HttpServletResponse resp = (HttpServletResponse) response;
resp.setHeader("Cache-Control", "no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
resp.setHeader("Pragma", "no-cache");

image

字段

HTTP1.0 缓存字段详解

  1. Pragma。 设置页面是否缓存,为Pragma则缓存,no-cache则不缓存。

  2. Expires。有了Pragma来禁用缓存,自然也需要有个东西来启用缓存和定义缓存时间。如果Pragma头部和Expires头部同时存在,则起作用的会是Pragma。,响应报文中Expires所定义的缓存时间是相对服务器上的时间而言的,其定义的是资源“失效时刻”,如果客户端上的时间跟服务器上的时间不一致(特别是用户修改了自己电脑的系统时间),那缓存时间可能就没啥意义了。

HTTP1.1 缓存字段详解

  1. Cache-Control: 定义缓存过期时间。若报文中同时出现了 Expires 和 Cache-Control,则以 Cache-Control 为准。

(1)max-age=600。 表示文件在本地应该缓存,且有效时长是600秒(从发出请求算起)。在接下来600秒内,如果有请求这个资源,浏览器不会发出 HTTP 请求,而是直接使用本地缓存的文件。

(2)no-cache。实际上她是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,==缓存都要向服务器评估缓存响应的有效性==

(3)no-store
响应不被缓存的意思。

  1. Last-Modified / If-Modified-Since

(1)Last-Modified: 标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。

(2)If-Modified-Since:
当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。若服务端请求资源的最后修改时间较新,则响应资源内容(HTTP 200);若最后修改时间较旧,则响应HTTP 304,告知浏览器继续使用所保存的cache。

  1. Etag/If-None-Match: Etag/If-None-Match也要配合Cache-Control使用。

(1)Etag: web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器觉得)

(2)If-None-Match: 当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。服务器与被请求资源的相应校验串进行比对,决定返回200或304。

  1. 既生Last-Modified何生Etag?

HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

(1) Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间。

(2) 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存。

(3) 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

小结

(1)浏览器第一次请求

image

(2) 浏览器第二次请求

image

缓存的作用

  • 减少网络带宽消耗。

无论对于网站运营者或者用户,带宽都代表着金钱,过多的带宽消耗,只会便宜了网络运营商。当Web缓存副本被使用时,只会产生极小的网络流量,可以有效的降低运营成本。

  • 降低服务器压力

给网络资源设定有效期之后,用户可以重复使用本地的缓存,减少对源服务器的请求,间接降低服务器的压力。同时,搜索引擎的爬虫机器人也能根据过期机制降低爬取的频率,也能有- 效降低服务器的压力。

  • 减少网络延迟,提升页面渲染速度

带宽对于个人网站运营者来说是十分重要,缓存的使用能够明显加快页面打开速度,达到更好的体验。

参考链接

https://juejin.im/entry/59c8d...

https://segmentfault.com/a/11...

https://mp.weixin.qq.com/s/qO...

https://segmentfault.com/a/11...


littlelightss
406 声望14 粉丝

« 上一篇
React diff算法