简述浏览器缓存是如何控制的

小饥从桌上醒来突然发现自己身处一个陌生的房间,面前是一台硕大无比学习机一样的电脑,身边有几个老外在忙忙碌碌敲打着键盘。

「这是哪里?」小饥有一百个疑问。面前有一个日记本,封面有一个机构标识 CERN (European Particle Physics Laboratory)。翻开笔记本第一页,一句话映入眼帘「我是Tim Berners-Lee , 世界上最帅的男人,这是我的小秘密不准看哦\~」。继续往下翻到最新的日记正文,只写了一个日期和几个关键字「Oct 31 1990, HTTP缓存到底怎么搞...」

难道穿越到了1990年?这里是欧洲粒子物理实验室?我就是大名鼎鼎的WWW的鼻祖 Tim Berners-Lee! 我的英文怎么突然变得这么好...

「Doctor Lee, 快点干活了,你昨天说的什么 HTTP 缓存赶紧出个方案明天大会上要讲。看你在睡觉没好意思打扰你,就先帮你应了下来...」 旁边走过来一个长发青年,一脸欠揍的模样。

小饥调整下心情,HTTP 缓存到底怎么实现呢?之前课堂上讲过怎么突然想不起来了... 从头开始捋一捋吧

1. 思路1,无缓存

浏览器向服务器请求资源 a.jpg,服务器找到对应资源把内容返回给浏览器。当浏览器再次向服务器请求资源a.jpg时,服务器重新发送完整的数据文件给浏览器。

2. 思路2,有缓存无更新

浏览器第一次请求a.jpg 时服务器会发送完整的文件,浏览器可以把这个文件存到本地(缓存),下次再需要这个文件时直接从本地获取就行了,这样就能省下带宽了。

3. 思路3, 缓存+更新机制

浏览器第一次请求a.jpg 时服务器会发送完整的文件,服务器在发送文件的时候还附带发送一些额外信息——过期时间,如 Expires: Mon,10 Dec 1990 02:25:22GMT。浏览器可以把这个文件和额外信息存到本地。当再次需要a.jpg的时候浏览器用当前浏览器时间和Expires做个比较,如果当前时间在过期时间以内,就直接使用缓存文件((200, from xx cache);如果在过期时间以外就重新向服务器发送请求要资源(200)。 服务器在每次给资源的时候都会发送新的过期时间

4. 思路4, 缓存+更新机制升级版

比如:浏览器第一次请求a.jpg 时,服务器会发送完整的文件并附带额外信息

Cache-Control: max-age=300;

浏览器把文件和附带信息保存起来。当再次需要a.jpg 时,如果是在300秒以内发起的请求则直接使用缓存(200, from xx cache),否则重新发起网络请求(200)。下面是Cache-Control常见的几个值:

优点:缓存控制功能更强大

缺点:假如浏览器再次请求资源a.jpg的时间间隔超过了max-age,这时候向服务器发送请求服务器应该会重新返回a.jpg的完整文件。但如果 a.jpg 在服务器上未做任何修改,发送a.jpg的完整文件就太浪费带宽了,其实只要发送一个「a.jpg未被更改」的短消息标示就好了。

5. 思路5, 缓存+更新机制终极版

比如:浏览器第一次请求a.jpg 时,服务器会发送完整的文件并附带额外信息,其中Etag 是 对a.jpg文件的编码,如果a.jpg在服务端未被修改,这个值就不会变

Cache-Control: max-age=300;
ETag:W/"e-cbxLFQW5zapn79tQwb/g6Q"

浏览器把a.jpg和额外信息保存到本地。假如浏览器在300秒以内再次需要获取a.jpg时,浏览器直接从缓存读取a.jpg(200, from xx cache)。假如浏览器在300秒之后再次需要获取a.jpg时,浏览器发现该缓存的文件已经不新鲜了,于是就向服务器发送请求 重新获取a.jpg, 在发送请求的时候附带刚刚保存的a.jpg的ETag ( If-None-Match:W/"e-cbxLFQW5zapn79tQwb/g6Q")。 服务器在接收到请求后拿浏览器请求的 Etag 和当前文件重新计算后端 Etag 做个比较,如果二者相等表示文件在未修改则发送个短消息(响应头,不包含图片内容, 304),如果二者不等则发送新文件和新的 ETag,浏览器获取新文件并更新该文件的 Etag。

与 ETag 类似功能的是Last-Modified/If-Modified-Since。当资源过期时(max-age超时),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示上次服务器告知的文件修改的时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(200);若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 ,告知浏览器继续使用所保存的cache。

小饥从梦中惊醒,发现自己竟然「发明」了HTTP缓存控制机制。感谢Tim Berners-Lee大神

饥人谷一直致力于培养有灵魂的编程者,打造专业有爱的国内前端技术圈子。如造梦师一般帮助近千名不甘寂寞的追梦人把编程梦变为现实,他们以饥人谷为起点,足迹遍布包括facebook、阿里巴巴、百度、网易、京东、今日头条、大众美团、饿了么、ofo在内的国内外大小企业。 了解培训课程:加微信 xiedaimala03,官网:https://jirengu.com

本文作者:饥人谷若愚老师