浏览器HTTP缓存
缓存的分类
缓存分为服务器端缓存和客户端缓存。
服务器缓存又分为代理服务器和反向代理服务器缓存,其中广泛应用的CDN也是一种服务器端缓存,目的都是让用户的请求走“捷径”,并且都是缓存图片,文件等静态资源。
客户端缓存一般指的是浏览器缓存,目的就是加速各种静态资源的访问,想想现在的大型网站,随便一个页面都是一两百个请求,每天pv(page view, 页面浏览量)都是亿级别,如果没有缓存,用户体验会急剧下降,同时服务器压力和网络带宽都面临严重的考验。
浏览器缓存机制详解
浏览器请求流程
-
浏览器第一次请求流程图
image -
浏览器再次请求流程图
image
重要概念
-
Expires策略
- 例: Expires:Wed, 10 Aug 2016 12:07:31 GMT
- Expires是Web服务器响应信息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。不过Expires是HTTP1.0 的东西,现在浏览器均默认使用HTTP1.1, 所以它的作用基本忽略。Expires的一个缺点就是,翻译的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间和服务器的时间相差很大,那么误差就很大,所以在HTTP1.1版开始,使用Cache-Control:max-age=秒 代替。
-
Cache-control策略
- 例: Cache-Control: public, max-age=676193
- Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发送请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires
- 有以下设置
- max-age(单位s)
- 指定设置缓存的最大有效时间。当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。即使服务器上的资源发生了变化,浏览器也不会得到通知。
- public
-
指定响应会被缓存,并且在多用户间共享,也就是下图的意思。如果没有指定为public还是private,则默认为public
image
-
- private
-
响应只作为私有的缓存,不能再用户间共享。如果要求HTTP认证,响应会自动设置为private
image
-
- no-cache
- 指定不缓存响应,表明资源不进行缓存
- 但是设置了no-cache之后并不代表浏览器不缓存,而是在缓存前要向服务器确认资源是否被更改。
- no-store
- 绝对禁止缓存,如果用了这个命令当然就是不会进行缓存啦~每次请求资源都要从服务器重新获取。
- max-age(单位s)
-
Last-Modified/If-Modified-Since策略
- 服务器端文件的最后修改时间,需要和Cache-Control共同使用,是检查服务器端资源是否更新的一种方式。当浏览器再次进行请求时,会向服务器发送If-Modified-Since报头,询问Last-modified时间点之后资源是否被修改过。如果没有修改,则返回码为304,使用缓存;如果修改过,则再次去服务器请求资源,返回码和首次请求相同为200,资源为服务器最新资源。
-
Etag/If-None-Match
- 根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是够修改过,如果没有修改,则返回码为304,使用缓存;如果修改过,则再次去服务器请求资源,返回码和首次请求时间为200,资源为服务器最新资源。
-
既生Last-Modified何生Etag?
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟之内被修改了很多次的话,它将不能准确标注文件的修改时间
- 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形