前段时间去面试移动端的H5开发工程师,在最后面试的时候被问到了max-age Expires Etag有什么不一样,在什么状况下应用,当时乱编了一通,自我感受良好,结果…… 你们懂得,如今讲他们几个的区别以及如何应用进行一下总结,方便后续查看。css
http/1.0中定义的header,是最基础的浏览器缓存处理,表示资源在必定时间内从浏览器的缓存中获取资源,不须要请求服务器获取资源,从而达到快速获取资源,缓解服务器压力的目的。html
在response的header中的格式为:Expires: Thu, 01 Dec 1994 16:00:00 GMT (必须是GMT格式)node
应用:
一、能够在html页面中添加<meta http-equiv="Expires" content="Thu, 01 Dec 1994 16:00:00"/> 来给页面设置缓存时间。
二、对于图片、css等文件则须要在IIS或者apache等运行容器中进行规则配置来让容器在请求资源的时候添加在responese的header中。面试
望文知义,根据这个词条的直译应该是上次修改(时间),经过修改服务器端的文件后再请求,发现response的header中的Last-modified改变了apache
更新原理:
一、在浏览器首次请求某个资源时,服务器端返回的状态码是200 (ok),内容是你请求的资源,同时有一个Last-Modified的属性标记(Reponse Header),标识此文件在服务期端最后被修改的时间,格式:Last-Modified:Tue, 24 Feb 2009 08:01:04 GMT浏览器
二、浏览器第二次请求该资源时,根据HTTP协议的规定,浏览器会向服务器传送If-Modified-Since报头(Request Header),询问该文件是否在指定时间以后有被修改过,格式为:If-Modified-Since:Tue, 24 Feb 2009 08:01:04 GMT缓存
三、若是服务器端的资源没有变化,则服务器返回304状态码(Not Modified),内容为空,这样就节省了传输数据量。当服务器端代码发生改变,则服务器返回200状态码(ok),内容为请求的资源,和第一次请求资源时相似。从而保证在资源没有修改时不向客户端重复发出资源,也保证当服务器有变化时,客户端可以及时获得最新的资源。服务器
注:若是If-Modified-Since的时间比服务器当前时间(当前的请求时间request_time)还晚,会认为是个非法请求负载均衡
http/1.1 中增长的header,HTTP协议规格说明定义ETag为“被请求变量的实体值” 。另外一种说法是,ETag是一个能够与Web资源关联的记号(token)。典型的Web资源能够一个Web页,但也多是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端。分布式
ETag的格式
不一样类型的Web服务器生成ETag的策略以及生成的格式是不一样的:
一、apache1.3和2.x的Etag格式是:inode-size-timestamp。
二、IIS5.0和6.0的Etag格式为Filetimestamp:Changenumber。
更新原理:
一、当浏览器首次请求资源的时候,服务器会返回200的状态码(ok),内容为请求的资源,同时response header会有一个ETag标记,该标记是服务器端根据容器(IIS或者Apache等等)中配置的ETag生成策略生成的一串惟一标识资源的字符串,ETag格式为 ETag:"856247206"
二、当浏览器第2次请求该资源时,浏览器会在传递给服务器的request中添加If-None-Match报头,询问服务器改文件在上次获取后是否修改了,报头格式:If-None-Match:"856246825"
三、服务器在获取到浏览器的请求后,会根据请求的资源查找对应的ETag,将当前服务器端指定资源对应的Etag与request中的If-None-Match进行对比,若是相同,说明资源没有修改,服务器返回304状态码(Not Modified),内容为空;若是对比发现不相同,则返回200状态码,同时将新的Etag添加到返回浏览器的response中。
Cache-Control中设置资源在本地缓存时间的一个值,单位为:秒(s),其余值还有private、no-cache、must-revalidate等
Expires存在HTTP 1.0 版本, 标识本地缓存的截止时间,容许浏览器在这个时间以前不去向服务器端发送请求验证资源是否有更新
max-age是HTTP 1.1版本新增的, 标识资源能够在本地缓存多少秒,存储的是更新间隔。
Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,若是浏览器所在机器的时间与服务器的时间相差很大,那么偏差就很大,因此在HTTP 1.1版开始,使用Cache-Control: max-age替代。
注: 若是max-age和Expires同时存在,则被Cache-Control的max-age覆盖。
Expires =max-age + “每次下载时的当前的request时间”
因此一旦从新下载的页面后,expires就从新计算一次,但last-modified不会变化
使用Last-Modified标识因为在资源未修改时返回的response内容为空,能够节省一点带宽,可是仍是逃不掉发一个HTTP请求出去,须要浏览器链接一次服务器端。
而Expires标识却使得浏览器干脆连HTTP请求都不用发,可是当用户使用F5或者点击Refresh按钮的时候,就算URI设置了Expires,浏览器同样也会发一个HTTP请求给服务器端,因此,Last-Modified仍是要用的,并且要和Expires一块儿用。
和 Last-Modified和Expires的状况相似,须要Expires控制请求的频率,Etag在强制刷新时做为保障
分布式系统里多台机器间文件的last-modified必须保持一致,以避免负载均衡到不一样机器致使比对失败,通常建议分布式系统尽可能关闭掉Etag(每台机器生成的etag都会不同)
Last-Modified和ETags请求的http报头一块儿使用,服务器首先产生Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改,来决定文件是否继续缓存
过程以下:
1.客户端请求一个页面(A)。
2.服务器返回页面A,并在给A加上一个Last-Modified/ETag。
3.客户端展示该页面,并将页面连同Last-Modified/ETag一块儿缓存。
4.客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一块儿传递给服务器。
5.服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求以后还未被修改,直接返回响应304和一个空的响应体。
从资源更新原理来看Last-Modified和Etag基本是相似的,那为何http协议中要搞2个标识呢?
Last-Modified存在的问题:一、在集群服务器上各个服务器上的文件时间可能不一样。二、若是用旧文件覆盖新文件,由于时间更前,浏览器不会请求这个更旧的文件。三、时间精度为s级,对文件修改精度有严格要求的场景不能知足