浏览器缓存对于现代网页是很是有用的功能,它能将大部分改变频率不大的组件缓存到本地以加速用户下次访问时页面的响应时间。
而与浏览器缓存相关的头有 expires,cache-control等等(如标题中提到的)
这些头信息分别表明什么呢?
由浅入深。首先咱们来讲说条件 GET 请求。
通常咱们向服务器发送http请求获取资源时服务器的响应头中通常会包含以下的一个头部信息:
Last-Modified : Wed, 22 Feb 2018 04:15:54 GMT
这个头部信息至关于告诉浏览器该资源的最近修改时间,浏览器收到响应后会将资源和这个时间缓存起来
等到下次请求相同资源的时候会在请求头中包含以下信息,以询问浏览器资源是否发生更改:
If-Modified-Since : Wed, 22 Feb 2018 04:15:54 GMT
服务器在收到请求后会与资源的修改最新修改时间进行对比,若是时间匹配,说明资源未发生更改并产生一个304响应,此时浏览器会返回以下头部信息:
HTTP 1.1 304 Not Modified
Last-Modified : Wed, 22 Feb 2018 04:15:54 GMT
这样服务器就无需向浏览器发送比这个响应大的多的文件自己,这大大节省了网页的响应时间。
但条件GET请求说到底仍是请求了后台(询问资源是否过时),若是组件长时间不会更新,那其实彻底无需向后台询问。可是咱们如何肯定资源是否过时呢?
这就用到Expires头了:
在浏览器向后台请求不常常更新的资源时,服务器通常会经过Expires返回一个有效期很长的过时时间:
Expires : Wed, 22 Feb 2019 04:15:54 GMT
浏览器收到响应后会把资源和这个时间缓存起来,等获得下次再次请求相同资源的时候,浏览器会对比这个时间
若是没有过时,浏览器会直接使用缓存中的资源而不会再次向服务器请求,这样直接就节省了一个http请求,何乐而不为?
说道这里,Expires看似很完美,但其实还有一个问题。
那就是Expires头使用一个特定的时间,他要求服务器和客户端的始终严格同步。另外,过时日期须要常常检查,而且一旦这一天到来了,还须要在服务其配置中提供一个新的日期。这固然是不符合程序员的性格的,我们要找的就是一劳永逸的方法!
因而Cache-Control来到了你的面前。
HTTP1.1 引入了Cache-control头来克服Expires头的限制。Cache-control使用max-age指令来指定组件被缓存多久。它以秒为单位定义了一个有效时间:
Cache-Control : max-age=315360000
若是从组件被请求开始过去的秒数少于max-age,浏览器就是用缓存中的版本,这样就避免了额外的http请求。
说完Cache-control,那么ETag又是啥?
ETag(Entity Tag)实体标签,是惟一标识了一个组件的一个特定版本的字符串。服务器确认组件是否过时有两种方式,一种就是上面提到的:对比过时时间,另外一种就是对比ETag字符串。
若是服务器启用了ETag,那么响应头中将包含以下请求头:
ETag : "10c345b-4cg-459e1c1f"
若是你的应用只有一台服务器,那么ETag是颇有用的,而且通常不会带来问题。
可是,因为不一样的服务器下彻底相同的资源都不可能拥有相同的ETag,同时若是响应头中同时带有ETag头和Expires头,那么必须保证二者都有效才会使用缓存。所以,通常状况下会更改ETag的配置,保证其在不一样的服务器上相同的资源有相同的ETag,或者彻底禁用ETag。
最后谢谢你的耐心阅读,若是此文对你有帮助,能够点个赞哦!