最近在准备优化日志请求时遇到了一些使人疑惑的问题,好比为何响应头里出现了两个 cache control、为何明明设置了 no cache 却仍是发请求,为何屡次访问时有时请求里带了 etag,有时又没有带?等等。。。html
后来查了一些资料以及同事亲自验证,总算对这些问题有了个清晰的理解,如今整理出来以备忘。node
缓存分为服务端侧(server side,好比 Nginx、Apache)和客户端侧(client side,好比 web browser)。web
服务端缓存又分为 代理服务器缓存 和 反向代理服务器缓存(也叫网关缓存,好比 Nginx反向代理、Squid等),其实普遍使用的 CDN 也是一种服务端缓存,目的都是让用户的请求走”捷径“,而且都是缓存图片、文件等静态资源。sql
客户端侧缓存通常指的是浏览器缓存,目的就是加速各类静态资源的访问,想一想如今的大型网站,随便一个页面都是一两百个请求,天天 pv 都是亿级别,若是没有缓存,用户体验会急剧降低、同时服务器压力和网络带宽都面临严重的考验。浏览器
浏览器缓存控制机制有两种:HTML Meta标签 vs. HTTP头信息缓存
浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如: Expires; Cache-control等)。可是也有非HTTP协议定义的缓存机制,如使用HTML Meta 标签,Web开发者能够在HTML页面的<head>节点中加入<meta>标签,代码以下:服务器
上述代码的做用是告诉浏览器当前页面不被缓存,每次访问都须要去服务器拉取。使用上很简单,但只有部分浏览器能够支持,并且全部缓存代理服务器都不支持,由于代理不解析HTML内容自己。而普遍应用的仍是 HTTP头信息 来控制缓存,下面我主要介绍HTTP协议定义的缓存机制。负载均衡
值能够是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age 各个消息中的指令含义以下: Public指示响应可被任何缓存区缓存。 Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这容许服务器仅仅描述当用户的部分响应消息,此响应消息对于其余用户的请求无效。 no-cache指示请求或响应消息不能缓存,该选项并非说能够设置”不缓存“,容易望文生义~ no-store用于防止重要的信息被无心的发布。在请求消息中发送将使得请求和响应消息都不使用缓存,彻底不存下來。 max-age指示客户机能够接收生存期不大于指定时间(以秒为单位)的响应。 min-fresh指示客户机能够接收响应时间小于当前时间加上指定时间的响应。 max-stale指示客户机能够接收超出超时期间的响应消息。若是指定max-stale消息的值,那么客户机能够接收超出超时期指定值以内的响应消息。
分布式
Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。 If-Modified-Since:当资源过时时(使用Cache-Control标识的max-age),发现资源具备Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的惟一标识符,可以更加准确的控制缓存。Last-Modified与ETag一块儿使用时,服务器会优先验证ETag。
浏览器缓存行为还有用户的行为有关,若是你们对 强制刷新(Ctrl + F5) 还有印象的话应该能马上明白个人意思~
用户操做 | Expires/Cache-Control | Last-Modified/Etag |
地址栏回车 | 有效 | 有效 |
页面连接跳转 | 有效 | 有效 |
新开窗口 | 有效 | 有效 |
前进、后退 | 有效 | 有效 |
F5/按钮刷新 | 无效(BR重置max-age=0) | 有效 |
Ctrl+F5刷新 | 无效(重置CC=no-cache) | 无效(请求头丢弃该选项) |
_______________________
原文地址:https://my.oschina.net/leejun2005/blog/369148