缓存分类
缓存分为服务器缓存(server side,比如nginx,apache)和客户端缓存(client side,比如web browser)
服务器端缓存又分为代理服务器缓存和反向代理服务器缓存(也叫网关缓存,比如nginx反向代理,squid等),广泛使用的cdn也是一种服务器缓存。
客户端缓存一般指的是浏览器端缓存,目的是加速各种静态资源访问,现在的大型站点,每个页面随便就是一两百个请求,每天pv都是亿级别,如果没有缓存,用户体验会急剧下降,同时服务器压力和网络带宽都面临严重考验。
客户端缓存
浏览器缓存分为两种,html meta标签以及http头信息
html meta标签
浏览器缓存机制除了http协议外,还可以使用meta标签,比如
<meta http-equiv="pragma" content="no-cache" />
上诉代码的作用就是告诉浏览器当前页面不被缓存,每次访问都需要重新去服务器取,使用上很简单,但只有部分浏览器支持,而且所有缓存代理服务器都不支持(代理服务器不解析html内容)
http信息头
浏览器请求流程如下
概念讲解
expires策略:expires是web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存读取数据,不需要再次请求,但是expires是http1.0的东西,现在浏览器默认使用http1.1,所以expires的作用基本可以忽略,expires的一个缺点是,返回的到期时间是服务器端的时间,这样就存在一个客户端和服务器端时区不一致的情况,会导致误差。http1.1使用cache-control:max-age=秒来代替expires。
cache-control策略:与expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存读取数据,只不过cache-control的选择更多,设置更细致。如果同时设置,优先级高于expires。cache-control取值可以是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/If-Modified-Since: Last-Modified/If-Modified-Since要配合Cache-Control使用
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/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用
Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。
If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。
既生Last-Modified 何生Etag,主要是因为etag解决了几个last-modified不能解决的问题
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
- 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag一起使用时,服务器会优先验证ETag
用户的行为与缓存的关系
浏览器缓存还与用户行为有关系,比如ctrl+f5。
备注:内容是从个人笔记里copy出来的,目的在于交流,进步。欢迎留言讨论