浏览器缓存对于现代网页是非常有用的功能,它能将大部分改变频率不大的应用组件缓存到本地以加速用户下次访问时页面的响应时间。
而与浏览器缓存相关的头有 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。
最后谢谢你的耐心阅读,如果此文对你有帮助,可以点个赞哦!